Update go dependencies

This commit is contained in:
Manuel de Brito Fontes 2017-11-12 14:14:23 -03:00
parent a858c549d9
commit f3bde94d68
643 changed files with 14296 additions and 19354 deletions

View file

@ -15,7 +15,6 @@ go_library(
"types.go",
"zz_generated.deepcopy.go",
],
importpath = "k8s.io/kubernetes/pkg/api",
visibility = ["//visibility:public"],
deps = [
"//vendor/k8s.io/apimachinery/pkg/api/resource:go_default_library",
@ -37,10 +36,53 @@ go_library(
go_test(
name = "go_default_test",
srcs = ["taint_test.go"],
importpath = "k8s.io/kubernetes/pkg/api",
library = ":go_default_library",
)
go_test(
name = "go_default_xtest",
srcs = [
"conversion_test.go",
"copy_test.go",
"deep_copy_test.go",
"defaulting_test.go",
"meta_test.go",
"serialization_proto_test.go",
"serialization_test.go",
"unstructured_test.go",
],
deps = [
":go_default_library",
"//pkg/api/testapi:go_default_library",
"//pkg/api/testing:go_default_library",
"//pkg/api/v1:go_default_library",
"//pkg/apis/extensions:go_default_library",
"//pkg/apis/extensions/v1beta1:go_default_library",
"//vendor/github.com/gogo/protobuf/proto:go_default_library",
"//vendor/github.com/golang/protobuf/proto:go_default_library",
"//vendor/github.com/google/gofuzz:go_default_library",
"//vendor/github.com/json-iterator/go:go_default_library",
"//vendor/k8s.io/api/core/v1:go_default_library",
"//vendor/k8s.io/api/extensions/v1beta1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/equality:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/meta:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/testing/fuzzer:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/testing/roundtrip:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/conversion:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/conversion/unstructured:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime/serializer/protobuf:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime/serializer/streaming:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/types:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/diff:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/json:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/watch:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
@ -65,6 +107,7 @@ filegroup(
"//pkg/api/testapi:all-srcs",
"//pkg/api/testing:all-srcs",
"//pkg/api/unversioned:all-srcs",
"//pkg/api/util:all-srcs",
"//pkg/api/v1:all-srcs",
"//pkg/api/validation:all-srcs",
],

117
vendor/k8s.io/kubernetes/pkg/api/conversion_test.go generated vendored Normal file
View file

@ -0,0 +1,117 @@
/*
Copyright 2015 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package api_test
import (
"io/ioutil"
"math/rand"
"testing"
apiequality "k8s.io/apimachinery/pkg/api/equality"
"k8s.io/apimachinery/pkg/api/testing/fuzzer"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/util/diff"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/testapi"
kapitesting "k8s.io/kubernetes/pkg/api/testing"
)
func BenchmarkPodConversion(b *testing.B) {
apiObjectFuzzer := fuzzer.FuzzerFor(kapitesting.FuzzerFuncs, rand.NewSource(benchmarkSeed), api.Codecs)
items := make([]api.Pod, 4)
for i := range items {
apiObjectFuzzer.Fuzz(&items[i])
items[i].Spec.InitContainers = nil
items[i].Status.InitContainerStatuses = nil
}
// add a fixed item
items = append(items, benchmarkPod)
width := len(items)
scheme := api.Scheme
for i := 0; i < b.N; i++ {
pod := &items[i%width]
versionedObj, err := scheme.UnsafeConvertToVersion(pod, api.Registry.GroupOrDie(api.GroupName).GroupVersion)
if err != nil {
b.Fatalf("Conversion error: %v", err)
}
if _, err = scheme.UnsafeConvertToVersion(versionedObj, testapi.Default.InternalGroupVersion()); err != nil {
b.Fatalf("Conversion error: %v", err)
}
}
}
func BenchmarkNodeConversion(b *testing.B) {
data, err := ioutil.ReadFile("node_example.json")
if err != nil {
b.Fatalf("Unexpected error while reading file: %v", err)
}
var node api.Node
if err := runtime.DecodeInto(testapi.Default.Codec(), data, &node); err != nil {
b.Fatalf("Unexpected error decoding node: %v", err)
}
scheme := api.Scheme
var result *api.Node
b.ResetTimer()
for i := 0; i < b.N; i++ {
versionedObj, err := scheme.UnsafeConvertToVersion(&node, api.Registry.GroupOrDie(api.GroupName).GroupVersion)
if err != nil {
b.Fatalf("Conversion error: %v", err)
}
obj, err := scheme.UnsafeConvertToVersion(versionedObj, testapi.Default.InternalGroupVersion())
if err != nil {
b.Fatalf("Conversion error: %v", err)
}
result = obj.(*api.Node)
}
b.StopTimer()
if !apiequality.Semantic.DeepDerivative(node, *result) {
b.Fatalf("Incorrect conversion: %s", diff.ObjectDiff(node, *result))
}
}
func BenchmarkReplicationControllerConversion(b *testing.B) {
data, err := ioutil.ReadFile("replication_controller_example.json")
if err != nil {
b.Fatalf("Unexpected error while reading file: %v", err)
}
var replicationController api.ReplicationController
if err := runtime.DecodeInto(testapi.Default.Codec(), data, &replicationController); err != nil {
b.Fatalf("Unexpected error decoding node: %v", err)
}
scheme := api.Scheme
var result *api.ReplicationController
b.ResetTimer()
for i := 0; i < b.N; i++ {
versionedObj, err := scheme.UnsafeConvertToVersion(&replicationController, api.Registry.GroupOrDie(api.GroupName).GroupVersion)
if err != nil {
b.Fatalf("Conversion error: %v", err)
}
obj, err := scheme.UnsafeConvertToVersion(versionedObj, testapi.Default.InternalGroupVersion())
if err != nil {
b.Fatalf("Conversion error: %v", err)
}
result = obj.(*api.ReplicationController)
}
b.StopTimer()
if !apiequality.Semantic.DeepDerivative(replicationController, *result) {
b.Fatalf("Incorrect conversion: expected %v, got %v", replicationController, *result)
}
}

87
vendor/k8s.io/kubernetes/pkg/api/copy_test.go generated vendored Normal file
View file

@ -0,0 +1,87 @@
/*
Copyright 2015 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package api_test
import (
"bytes"
"math/rand"
"reflect"
"testing"
"github.com/google/gofuzz"
"k8s.io/apimachinery/pkg/api/testing/fuzzer"
"k8s.io/apimachinery/pkg/api/testing/roundtrip"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/util/diff"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/testapi"
kapitesting "k8s.io/kubernetes/pkg/api/testing"
)
func TestDeepCopyApiObjects(t *testing.T) {
for i := 0; i < *roundtrip.FuzzIters; i++ {
for _, version := range []schema.GroupVersion{testapi.Default.InternalGroupVersion(), api.Registry.GroupOrDie(api.GroupName).GroupVersion} {
f := fuzzer.FuzzerFor(kapitesting.FuzzerFuncs, rand.NewSource(rand.Int63()), api.Codecs)
for kind := range api.Scheme.KnownTypes(version) {
doDeepCopyTest(t, version.WithKind(kind), f)
}
}
}
}
func doDeepCopyTest(t *testing.T, kind schema.GroupVersionKind, f *fuzz.Fuzzer) {
item, err := api.Scheme.New(kind)
if err != nil {
t.Fatalf("Could not create a %v: %s", kind, err)
}
f.Fuzz(item)
itemCopy := item.DeepCopyObject()
if !reflect.DeepEqual(item, itemCopy) {
t.Errorf("\nexpected: %#v\n\ngot: %#v\n\ndiff: %v", item, itemCopy, diff.ObjectReflectDiff(item, itemCopy))
}
prefuzzData := &bytes.Buffer{}
if err := api.Codecs.LegacyCodec(kind.GroupVersion()).Encode(item, prefuzzData); err != nil {
t.Errorf("Could not encode a %v: %s", kind, err)
return
}
// Refuzz the copy, which should have no effect on the original
f.Fuzz(itemCopy)
postfuzzData := &bytes.Buffer{}
if err := api.Codecs.LegacyCodec(kind.GroupVersion()).Encode(item, postfuzzData); err != nil {
t.Errorf("Could not encode a %v: %s", kind, err)
return
}
if bytes.Compare(prefuzzData.Bytes(), postfuzzData.Bytes()) != 0 {
t.Log(diff.StringDiff(prefuzzData.String(), postfuzzData.String()))
t.Errorf("Fuzzing copy modified original of %#v", kind)
return
}
}
func TestDeepCopySingleType(t *testing.T) {
for i := 0; i < *roundtrip.FuzzIters; i++ {
for _, version := range []schema.GroupVersion{testapi.Default.InternalGroupVersion(), api.Registry.GroupOrDie(api.GroupName).GroupVersion} {
f := fuzzer.FuzzerFor(kapitesting.FuzzerFuncs, rand.NewSource(rand.Int63()), api.Codecs)
doDeepCopyTest(t, version.WithKind("Pod"), f)
}
}
}

177
vendor/k8s.io/kubernetes/pkg/api/deep_copy_test.go generated vendored Normal file
View file

@ -0,0 +1,177 @@
/*
Copyright 2015 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package api_test
import (
"io/ioutil"
"testing"
"time"
apiequality "k8s.io/apimachinery/pkg/api/equality"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/testapi"
)
func parseTimeOrDie(ts string) metav1.Time {
t, err := time.Parse(time.RFC3339, ts)
if err != nil {
panic(err)
}
return metav1.Time{Time: t}
}
var benchmarkPod api.Pod = api.Pod{
TypeMeta: metav1.TypeMeta{
Kind: "Pod",
APIVersion: "v1",
},
ObjectMeta: metav1.ObjectMeta{
Name: "etcd-server-e2e-test-wojtekt-master",
Namespace: "default",
SelfLink: "/api/v1/namespaces/default/pods/etcd-server-e2e-test-wojtekt-master",
UID: types.UID("a671734a-e8e5-11e4-8fde-42010af09327"),
ResourceVersion: "22",
CreationTimestamp: parseTimeOrDie("2015-04-22T11:49:36Z"),
},
Spec: api.PodSpec{
Volumes: []api.Volume{
{
Name: "varetcd",
VolumeSource: api.VolumeSource{
HostPath: &api.HostPathVolumeSource{
Path: "/mnt/master-pd/var/etcd",
},
},
},
},
Containers: []api.Container{
{
Name: "etcd-container",
Image: "gcr.io/google_containers/etcd:2.0.9",
Command: []string{
"/usr/local/bin/etcd",
"--addr",
"127.0.0.1:2379",
"--bind-addr",
"127.0.0.1:2379",
"--data-dir",
"/var/etcd/data",
},
Ports: []api.ContainerPort{
{
Name: "serverport",
HostPort: 2380,
ContainerPort: 2380,
Protocol: "TCP",
},
{
Name: "clientport",
HostPort: 2379,
ContainerPort: 2379,
Protocol: "TCP",
},
},
VolumeMounts: []api.VolumeMount{
{
Name: "varetcd",
MountPath: "/var/etcd",
},
},
TerminationMessagePath: "/dev/termination-log",
ImagePullPolicy: api.PullIfNotPresent,
},
},
RestartPolicy: api.RestartPolicyAlways,
DNSPolicy: api.DNSClusterFirst,
NodeName: "e2e-test-wojtekt-master",
},
Status: api.PodStatus{
Phase: api.PodRunning,
Conditions: []api.PodCondition{
{
Type: api.PodReady,
Status: api.ConditionTrue,
},
},
ContainerStatuses: []api.ContainerStatus{
{
Name: "etcd-container",
State: api.ContainerState{
Running: &api.ContainerStateRunning{
StartedAt: parseTimeOrDie("2015-04-22T11:49:32Z"),
},
},
Ready: true,
RestartCount: 0,
Image: "gcr.io/google_containers/etcd:2.0.9",
ImageID: "docker://b6b9a86dc06aa1361357ca1b105feba961f6a4145adca6c54e142c0be0fe87b0",
ContainerID: "docker://3cbbf818f1addfc252957b4504f56ef2907a313fe6afc47fc75373674255d46d",
},
},
},
}
func BenchmarkPodCopy(b *testing.B) {
var result *api.Pod
for i := 0; i < b.N; i++ {
result = benchmarkPod.DeepCopy()
}
if !apiequality.Semantic.DeepEqual(benchmarkPod, *result) {
b.Fatalf("Incorrect copy: expected %v, got %v", benchmarkPod, *result)
}
}
func BenchmarkNodeCopy(b *testing.B) {
data, err := ioutil.ReadFile("node_example.json")
if err != nil {
b.Fatalf("Unexpected error while reading file: %v", err)
}
var node api.Node
if err := runtime.DecodeInto(testapi.Default.Codec(), data, &node); err != nil {
b.Fatalf("Unexpected error decoding node: %v", err)
}
var result *api.Node
for i := 0; i < b.N; i++ {
result = node.DeepCopy()
}
if !apiequality.Semantic.DeepEqual(node, *result) {
b.Fatalf("Incorrect copy: expected %v, got %v", node, *result)
}
}
func BenchmarkReplicationControllerCopy(b *testing.B) {
data, err := ioutil.ReadFile("replication_controller_example.json")
if err != nil {
b.Fatalf("Unexpected error while reading file: %v", err)
}
var replicationController api.ReplicationController
if err := runtime.DecodeInto(testapi.Default.Codec(), data, &replicationController); err != nil {
b.Fatalf("Unexpected error decoding node: %v", err)
}
var result *api.ReplicationController
for i := 0; i < b.N; i++ {
result = replicationController.DeepCopy()
}
if !apiequality.Semantic.DeepEqual(replicationController, *result) {
b.Fatalf("Incorrect copy: expected %v, got %v", replicationController, *result)
}
}

225
vendor/k8s.io/kubernetes/pkg/api/defaulting_test.go generated vendored Normal file
View file

@ -0,0 +1,225 @@
/*
Copyright 2016 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package api_test
import (
"math/rand"
"reflect"
"sort"
"testing"
fuzz "github.com/google/gofuzz"
apiv1 "k8s.io/api/core/v1"
extensionsv1beta1 "k8s.io/api/extensions/v1beta1"
roundtrip "k8s.io/apimachinery/pkg/api/testing/roundtrip"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/util/diff"
"k8s.io/kubernetes/pkg/api"
)
type orderedGroupVersionKinds []schema.GroupVersionKind
func (o orderedGroupVersionKinds) Len() int { return len(o) }
func (o orderedGroupVersionKinds) Swap(i, j int) { o[i], o[j] = o[j], o[i] }
func (o orderedGroupVersionKinds) Less(i, j int) bool {
return o[i].String() < o[j].String()
}
// TODO: add a reflexive test that verifies that all SetDefaults functions are registered
func TestDefaulting(t *testing.T) {
// these are the known types with defaulters - you must add to this list if you add a top level defaulter
typesWithDefaulting := map[schema.GroupVersionKind]struct{}{
{Group: "", Version: "v1", Kind: "ConfigMap"}: {},
{Group: "", Version: "v1", Kind: "ConfigMapList"}: {},
{Group: "", Version: "v1", Kind: "Endpoints"}: {},
{Group: "", Version: "v1", Kind: "EndpointsList"}: {},
{Group: "", Version: "v1", Kind: "Namespace"}: {},
{Group: "", Version: "v1", Kind: "NamespaceList"}: {},
{Group: "", Version: "v1", Kind: "Node"}: {},
{Group: "", Version: "v1", Kind: "NodeList"}: {},
{Group: "", Version: "v1", Kind: "PersistentVolume"}: {},
{Group: "", Version: "v1", Kind: "PersistentVolumeList"}: {},
{Group: "", Version: "v1", Kind: "PersistentVolumeClaim"}: {},
{Group: "", Version: "v1", Kind: "PersistentVolumeClaimList"}: {},
{Group: "", Version: "v1", Kind: "PodAttachOptions"}: {},
{Group: "", Version: "v1", Kind: "PodExecOptions"}: {},
{Group: "", Version: "v1", Kind: "Pod"}: {},
{Group: "", Version: "v1", Kind: "PodList"}: {},
{Group: "", Version: "v1", Kind: "PodTemplate"}: {},
{Group: "", Version: "v1", Kind: "PodTemplateList"}: {},
{Group: "", Version: "v1", Kind: "ReplicationController"}: {},
{Group: "", Version: "v1", Kind: "ReplicationControllerList"}: {},
{Group: "", Version: "v1", Kind: "Secret"}: {},
{Group: "", Version: "v1", Kind: "SecretList"}: {},
{Group: "", Version: "v1", Kind: "Service"}: {},
{Group: "", Version: "v1", Kind: "ServiceList"}: {},
{Group: "apps", Version: "v1beta1", Kind: "StatefulSet"}: {},
{Group: "apps", Version: "v1beta1", Kind: "StatefulSetList"}: {},
{Group: "apps", Version: "v1beta2", Kind: "StatefulSet"}: {},
{Group: "apps", Version: "v1beta2", Kind: "StatefulSetList"}: {},
{Group: "autoscaling", Version: "v1", Kind: "HorizontalPodAutoscaler"}: {},
{Group: "autoscaling", Version: "v1", Kind: "HorizontalPodAutoscalerList"}: {},
{Group: "autoscaling", Version: "v2beta1", Kind: "HorizontalPodAutoscaler"}: {},
{Group: "autoscaling", Version: "v2beta1", Kind: "HorizontalPodAutoscalerList"}: {},
{Group: "batch", Version: "v1", Kind: "Job"}: {},
{Group: "batch", Version: "v1", Kind: "JobList"}: {},
{Group: "batch", Version: "v1beta1", Kind: "CronJob"}: {},
{Group: "batch", Version: "v1beta1", Kind: "CronJobList"}: {},
{Group: "batch", Version: "v1beta1", Kind: "JobTemplate"}: {},
{Group: "batch", Version: "v2alpha1", Kind: "CronJob"}: {},
{Group: "batch", Version: "v2alpha1", Kind: "CronJobList"}: {},
{Group: "batch", Version: "v2alpha1", Kind: "JobTemplate"}: {},
{Group: "certificates.k8s.io", Version: "v1beta1", Kind: "CertificateSigningRequest"}: {},
{Group: "certificates.k8s.io", Version: "v1beta1", Kind: "CertificateSigningRequestList"}: {},
{Group: "componentconfig", Version: "v1alpha1", Kind: "KubeProxyConfiguration"}: {},
{Group: "componentconfig", Version: "v1alpha1", Kind: "KubeSchedulerConfiguration"}: {},
{Group: "componentconfig", Version: "v1alpha1", Kind: "KubeletConfiguration"}: {},
{Group: "kubeadm.k8s.io", Version: "v1alpha1", Kind: "MasterConfiguration"}: {},
// This object contains only int fields which currently breaks the defaulting test because
// it's pretty stupid. Once we add non integer fields, we should uncomment this.
// {Group: "kubeadm.k8s.io", Version: "v1alpha1", Kind: "NodeConfiguration"}: {},
{Group: "extensions", Version: "v1beta1", Kind: "DaemonSet"}: {},
{Group: "extensions", Version: "v1beta1", Kind: "DaemonSetList"}: {},
{Group: "apps", Version: "v1beta2", Kind: "DaemonSet"}: {},
{Group: "apps", Version: "v1beta2", Kind: "DaemonSetList"}: {},
{Group: "extensions", Version: "v1beta1", Kind: "Deployment"}: {},
{Group: "extensions", Version: "v1beta1", Kind: "DeploymentList"}: {},
{Group: "apps", Version: "v1beta1", Kind: "Deployment"}: {},
{Group: "apps", Version: "v1beta1", Kind: "DeploymentList"}: {},
{Group: "apps", Version: "v1beta2", Kind: "Deployment"}: {},
{Group: "apps", Version: "v1beta2", Kind: "DeploymentList"}: {},
{Group: "extensions", Version: "v1beta1", Kind: "PodSecurityPolicy"}: {},
{Group: "extensions", Version: "v1beta1", Kind: "PodSecurityPolicyList"}: {},
{Group: "apps", Version: "v1beta2", Kind: "ReplicaSet"}: {},
{Group: "apps", Version: "v1beta2", Kind: "ReplicaSetList"}: {},
{Group: "extensions", Version: "v1beta1", Kind: "ReplicaSet"}: {},
{Group: "extensions", Version: "v1beta1", Kind: "ReplicaSetList"}: {},
{Group: "extensions", Version: "v1beta1", Kind: "NetworkPolicy"}: {},
{Group: "extensions", Version: "v1beta1", Kind: "NetworkPolicyList"}: {},
{Group: "rbac.authorization.k8s.io", Version: "v1alpha1", Kind: "ClusterRoleBinding"}: {},
{Group: "rbac.authorization.k8s.io", Version: "v1alpha1", Kind: "ClusterRoleBindingList"}: {},
{Group: "rbac.authorization.k8s.io", Version: "v1alpha1", Kind: "RoleBinding"}: {},
{Group: "rbac.authorization.k8s.io", Version: "v1alpha1", Kind: "RoleBindingList"}: {},
{Group: "rbac.authorization.k8s.io", Version: "v1beta1", Kind: "ClusterRoleBinding"}: {},
{Group: "rbac.authorization.k8s.io", Version: "v1beta1", Kind: "ClusterRoleBindingList"}: {},
{Group: "rbac.authorization.k8s.io", Version: "v1beta1", Kind: "RoleBinding"}: {},
{Group: "rbac.authorization.k8s.io", Version: "v1beta1", Kind: "RoleBindingList"}: {},
{Group: "rbac.authorization.k8s.io", Version: "v1", Kind: "ClusterRoleBinding"}: {},
{Group: "rbac.authorization.k8s.io", Version: "v1", Kind: "ClusterRoleBindingList"}: {},
{Group: "rbac.authorization.k8s.io", Version: "v1", Kind: "RoleBinding"}: {},
{Group: "rbac.authorization.k8s.io", Version: "v1", Kind: "RoleBindingList"}: {},
{Group: "settings.k8s.io", Version: "v1alpha1", Kind: "PodPreset"}: {},
{Group: "settings.k8s.io", Version: "v1alpha1", Kind: "PodPresetList"}: {},
{Group: "admissionregistration.k8s.io", Version: "v1alpha1", Kind: "ExternalAdmissionHookConfiguration"}: {},
{Group: "admissionregistration.k8s.io", Version: "v1alpha1", Kind: "ExternalAdmissionHookConfigurationList"}: {},
{Group: "networking.k8s.io", Version: "v1", Kind: "NetworkPolicy"}: {},
{Group: "networking.k8s.io", Version: "v1", Kind: "NetworkPolicyList"}: {},
{Group: "storage.k8s.io", Version: "v1beta1", Kind: "StorageClass"}: {},
{Group: "storage.k8s.io", Version: "v1beta1", Kind: "StorageClassList"}: {},
{Group: "storage.k8s.io", Version: "v1", Kind: "StorageClass"}: {},
{Group: "storage.k8s.io", Version: "v1", Kind: "StorageClassList"}: {},
}
f := fuzz.New().NilChance(.5).NumElements(1, 1).RandSource(rand.NewSource(1))
f.Funcs(
func(s *runtime.RawExtension, c fuzz.Continue) {},
func(s *metav1.LabelSelector, c fuzz.Continue) {
c.FuzzNoCustom(s)
s.MatchExpressions = nil // need to fuzz this specially
},
func(s *apiv1.ListOptions, c fuzz.Continue) {
c.FuzzNoCustom(s)
s.LabelSelector = "" // need to fuzz requirement strings specially
s.FieldSelector = "" // need to fuzz requirement strings specially
},
func(s *extensionsv1beta1.ScaleStatus, c fuzz.Continue) {
c.FuzzNoCustom(s)
s.TargetSelector = "" // need to fuzz requirement strings specially
},
)
scheme := api.Scheme
var testTypes orderedGroupVersionKinds
for gvk := range scheme.AllKnownTypes() {
if gvk.Version == runtime.APIVersionInternal {
continue
}
testTypes = append(testTypes, gvk)
}
sort.Sort(testTypes)
for _, gvk := range testTypes {
_, expectedChanged := typesWithDefaulting[gvk]
iter := 0
changedOnce := false
for {
if iter > *roundtrip.FuzzIters {
if !expectedChanged || changedOnce {
break
}
if iter > 300 {
t.Errorf("expected %s to trigger defaulting due to fuzzing", gvk)
break
}
// if we expected defaulting, continue looping until the fuzzer gives us one
// at worst, we will timeout
}
iter++
src, err := scheme.New(gvk)
if err != nil {
t.Fatal(err)
}
f.Fuzz(src)
src.GetObjectKind().SetGroupVersionKind(schema.GroupVersionKind{})
original := src.DeepCopyObject()
// get internal
withDefaults := src.DeepCopyObject()
scheme.Default(withDefaults.(runtime.Object))
if !reflect.DeepEqual(original, withDefaults) {
changedOnce = true
if !expectedChanged {
t.Errorf("{Group: \"%s\", Version: \"%s\", Kind: \"%s\"} did not expect defaults to be set - update expected or check defaulter registering: %s", gvk.Group, gvk.Version, gvk.Kind, diff.ObjectReflectDiff(original, withDefaults))
}
}
}
}
}
func BenchmarkPodDefaulting(b *testing.B) {
f := fuzz.New().NilChance(.5).NumElements(1, 1).RandSource(rand.NewSource(1))
items := make([]apiv1.Pod, 100)
for i := range items {
f.Fuzz(&items[i])
}
scheme := api.Scheme
b.ResetTimer()
for i := 0; i < b.N; i++ {
pod := &items[i%len(items)]
scheme.Default(pod)
}
b.StopTimer()
}

View file

@ -9,7 +9,6 @@ load(
go_test(
name = "go_default_test",
srcs = ["helpers_test.go"],
importpath = "k8s.io/kubernetes/pkg/api/helper",
library = ":go_default_library",
deps = [
"//pkg/api:go_default_library",
@ -21,7 +20,6 @@ go_test(
go_library(
name = "go_default_library",
srcs = ["helpers.go"],
importpath = "k8s.io/kubernetes/pkg/api/helper",
deps = [
"//pkg/api:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/resource:go_default_library",

View file

@ -265,11 +265,6 @@ func IsIntegerResourceName(str string) bool {
return integerResources.Has(str) || IsExtendedResourceName(api.ResourceName(str))
}
// Extended and HugePages resources
func IsScalarResourceName(name api.ResourceName) bool {
return IsExtendedResourceName(name) || IsHugePageResourceName(name)
}
// this function aims to check if the service's ClusterIP is set or not
// the objective is not to perform validation here
func IsServiceIPSet(service *api.Service) bool {

View file

@ -9,7 +9,6 @@ load(
go_library(
name = "go_default_library",
srcs = ["install.go"],
importpath = "k8s.io/kubernetes/pkg/api/install",
deps = [
"//pkg/api:go_default_library",
"//pkg/api/v1:go_default_library",
@ -23,7 +22,6 @@ go_library(
go_test(
name = "go_default_test",
srcs = ["install_test.go"],
importpath = "k8s.io/kubernetes/pkg/api/install",
library = ":go_default_library",
deps = [
"//pkg/api:go_default_library",

103
vendor/k8s.io/kubernetes/pkg/api/meta_test.go generated vendored Normal file
View file

@ -0,0 +1,103 @@
/*
Copyright 2014 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package api_test
import (
"reflect"
"testing"
"k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/kubernetes/pkg/api"
)
var _ metav1.Object = &metav1.ObjectMeta{}
func TestAccessorImplementations(t *testing.T) {
for _, gv := range api.Registry.EnabledVersions() {
internalGV := schema.GroupVersion{Group: gv.Group, Version: runtime.APIVersionInternal}
for _, gv := range []schema.GroupVersion{gv, internalGV} {
for kind, knownType := range api.Scheme.KnownTypes(gv) {
value := reflect.New(knownType)
obj := value.Interface()
if _, ok := obj.(runtime.Object); !ok {
t.Errorf("%v (%v) does not implement runtime.Object", gv.WithKind(kind), knownType)
}
lm, isLM := obj.(meta.ListMetaAccessor)
om, isOM := obj.(metav1.ObjectMetaAccessor)
switch {
case isLM && isOM:
t.Errorf("%v (%v) implements ListMetaAccessor and ObjectMetaAccessor", gv.WithKind(kind), knownType)
continue
case isLM:
m := lm.GetListMeta()
if m == nil {
t.Errorf("%v (%v) returns nil ListMeta", gv.WithKind(kind), knownType)
continue
}
m.SetResourceVersion("102030")
if m.GetResourceVersion() != "102030" {
t.Errorf("%v (%v) did not preserve resource version", gv.WithKind(kind), knownType)
continue
}
m.SetSelfLink("102030")
if m.GetSelfLink() != "102030" {
t.Errorf("%v (%v) did not preserve self link", gv.WithKind(kind), knownType)
continue
}
case isOM:
m := om.GetObjectMeta()
if m == nil {
t.Errorf("%v (%v) returns nil ObjectMeta", gv.WithKind(kind), knownType)
continue
}
m.SetResourceVersion("102030")
if m.GetResourceVersion() != "102030" {
t.Errorf("%v (%v) did not preserve resource version", gv.WithKind(kind), knownType)
continue
}
m.SetSelfLink("102030")
if m.GetSelfLink() != "102030" {
t.Errorf("%v (%v) did not preserve self link", gv.WithKind(kind), knownType)
continue
}
labels := map[string]string{"a": "b"}
m.SetLabels(labels)
if !reflect.DeepEqual(m.GetLabels(), labels) {
t.Errorf("%v (%v) did not preserve labels", gv.WithKind(kind), knownType)
continue
}
default:
if _, ok := obj.(metav1.ListMetaAccessor); ok {
continue
}
if _, ok := value.Elem().Type().FieldByName("ObjectMeta"); ok {
t.Errorf("%v (%v) has ObjectMeta but does not implement ObjectMetaAccessor", gv.WithKind(kind), knownType)
continue
}
if _, ok := value.Elem().Type().FieldByName("ListMeta"); ok {
t.Errorf("%v (%v) has ListMeta but does not implement ListMetaAccessor", gv.WithKind(kind), knownType)
continue
}
t.Logf("%v (%v) does not implement ListMetaAccessor or ObjectMetaAccessor", gv.WithKind(kind), knownType)
}
}
}
}
}

49
vendor/k8s.io/kubernetes/pkg/api/node_example.json generated vendored Normal file
View file

@ -0,0 +1,49 @@
{
"kind": "Node",
"apiVersion": "v1",
"metadata": {
"name": "e2e-test-wojtekt-node-etd6",
"selfLink": "/api/v1/nodes/e2e-test-wojtekt-node-etd6",
"uid": "a7e89222-e8e5-11e4-8fde-42010af09327",
"resourceVersion": "379",
"creationTimestamp": "2015-04-22T11:49:39Z"
},
"spec": {
"externalID": "15488322946290398375"
},
"status": {
"capacity": {
"cpu": "1",
"memory": "1745152Ki"
},
"conditions": [
{
"type": "Ready",
"status": "True",
"lastHeartbeatTime": "2015-04-22T11:58:17Z",
"lastTransitionTime": "2015-04-22T11:49:52Z",
"reason": "kubelet is posting ready status"
}
],
"addresses": [
{
"type": "ExternalIP",
"address": "104.197.49.213"
},
{
"type": "LegacyHostIP",
"address": "104.197.20.11"
}
],
"nodeInfo": {
"machineID": "",
"systemUUID": "D59FA3FA-7B5B-7287-5E1A-1D79F13CB577",
"bootID": "44a832f3-8cfb-4de5-b7d2-d66030b6cd95",
"kernelVersion": "3.16.0-0.bpo.4-amd64",
"osImage": "Debian GNU/Linux 7 (wheezy)",
"containerRuntimeVersion": "docker://1.5.0",
"kubeletVersion": "v0.15.0-484-g0c8ee980d705a3-dirty",
"kubeProxyVersion": "v0.15.0-484-g0c8ee980d705a3-dirty"
}
}
}

View file

@ -0,0 +1,83 @@
{
"kind": "ReplicationController",
"apiVersion": "v1",
"metadata": {
"name": "elasticsearch-logging-controller",
"namespace": "default",
"selfLink": "/api/v1/namespaces/default/replicationcontrollers/elasticsearch-logging-controller",
"uid": "aa76f162-e8e5-11e4-8fde-42010af09327",
"resourceVersion": "98",
"creationTimestamp": "2015-04-22T11:49:43Z",
"labels": {
"kubernetes.io/cluster-service": "true",
"name": "elasticsearch-logging"
}
},
"spec": {
"replicas": 1,
"selector": {
"name": "elasticsearch-logging"
},
"template": {
"metadata": {
"creationTimestamp": null,
"labels": {
"kubernetes.io/cluster-service": "true",
"name": "elasticsearch-logging"
}
},
"spec": {
"volumes": [
{
"name": "es-persistent-storage",
"hostPath": null,
"emptyDir": {
"medium": ""
},
"gcePersistentDisk": null,
"awsElasticBlockStore": null,
"gitRepo": null,
"secret": null,
"nfs": null,
"iscsi": null,
"glusterfs": null,
"quobyte": null
}
],
"containers": [
{
"name": "elasticsearch-logging",
"image": "gcr.io/google_containers/elasticsearch:1.0",
"ports": [
{
"name": "db",
"containerPort": 9200,
"protocol": "TCP"
},
{
"name": "transport",
"containerPort": 9300,
"protocol": "TCP"
}
],
"resources": {},
"volumeMounts": [
{
"name": "es-persistent-storage",
"mountPath": "/data"
}
],
"terminationMessagePath": "/dev/termination-log",
"imagePullPolicy": "IfNotPresent",
"capabilities": {}
}
],
"restartPolicy": "Always",
"dnsPolicy": "ClusterFirst"
}
}
},
"status": {
"replicas": 1
}
}

View file

@ -0,0 +1,217 @@
/*
Copyright 2015 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package api_test
import (
"bytes"
"encoding/hex"
"fmt"
"math/rand"
"reflect"
"testing"
"github.com/gogo/protobuf/proto"
"k8s.io/api/core/v1"
apiequality "k8s.io/apimachinery/pkg/api/equality"
"k8s.io/apimachinery/pkg/api/testing/fuzzer"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/runtime/serializer/protobuf"
"k8s.io/apimachinery/pkg/util/diff"
"k8s.io/kubernetes/pkg/api"
kapitesting "k8s.io/kubernetes/pkg/api/testing"
_ "k8s.io/kubernetes/pkg/apis/extensions"
_ "k8s.io/kubernetes/pkg/apis/extensions/v1beta1"
)
func TestUniversalDeserializer(t *testing.T) {
expected := &v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "test"}}
d := api.Codecs.UniversalDeserializer()
for _, mediaType := range []string{"application/json", "application/yaml", "application/vnd.kubernetes.protobuf"} {
info, ok := runtime.SerializerInfoForMediaType(api.Codecs.SupportedMediaTypes(), mediaType)
if !ok {
t.Fatal(mediaType)
}
buf := &bytes.Buffer{}
if err := info.Serializer.Encode(expected, buf); err != nil {
t.Fatalf("%s: %v", mediaType, err)
}
obj, _, err := d.Decode(buf.Bytes(), &schema.GroupVersionKind{Kind: "Pod", Version: "v1"}, nil)
if err != nil {
t.Fatalf("%s: %v", mediaType, err)
}
if !apiequality.Semantic.DeepEqual(expected, obj) {
t.Fatalf("%s: %#v", mediaType, obj)
}
}
}
func TestAllFieldsHaveTags(t *testing.T) {
for gvk, obj := range api.Scheme.AllKnownTypes() {
if gvk.Version == runtime.APIVersionInternal {
// internal versions are not serialized to protobuf
continue
}
if gvk.Group == "componentconfig" {
// component config is not serialized to protobuf
continue
}
if err := fieldsHaveProtobufTags(obj); err != nil {
t.Errorf("type %s as gvk %v is missing tags: %v", obj, gvk, err)
}
}
}
func fieldsHaveProtobufTags(obj reflect.Type) error {
switch obj.Kind() {
case reflect.Slice, reflect.Map, reflect.Ptr, reflect.Array:
return fieldsHaveProtobufTags(obj.Elem())
case reflect.Struct:
for i := 0; i < obj.NumField(); i++ {
f := obj.Field(i)
if f.Name == "TypeMeta" && f.Type.Name() == "TypeMeta" {
// TypeMeta is not included in external protobuf because we use an envelope type with TypeMeta
continue
}
if len(f.Tag.Get("json")) > 0 && len(f.Tag.Get("protobuf")) == 0 {
return fmt.Errorf("field %s in %s has a 'json' tag but no protobuf tag", f.Name, obj)
}
}
}
return nil
}
func TestProtobufRoundTrip(t *testing.T) {
obj := &v1.Pod{}
fuzzer.FuzzerFor(kapitesting.FuzzerFuncs, rand.NewSource(benchmarkSeed), api.Codecs).Fuzz(obj)
// InitContainers are turned into annotations by conversion.
obj.Spec.InitContainers = nil
obj.Status.InitContainerStatuses = nil
data, err := obj.Marshal()
if err != nil {
t.Fatal(err)
}
out := &v1.Pod{}
if err := out.Unmarshal(data); err != nil {
t.Fatal(err)
}
if !apiequality.Semantic.Equalities.DeepEqual(out, obj) {
t.Logf("marshal\n%s", hex.Dump(data))
t.Fatalf("Unmarshal is unequal\n%s", diff.ObjectGoPrintDiff(out, obj))
}
}
// BenchmarkEncodeCodec measures the cost of performing a codec encode, which includes
// reflection (to clear APIVersion and Kind)
func BenchmarkEncodeCodecProtobuf(b *testing.B) {
items := benchmarkItems(b)
width := len(items)
s := protobuf.NewSerializer(nil, nil, "application/arbitrary.content.type")
b.ResetTimer()
for i := 0; i < b.N; i++ {
if _, err := runtime.Encode(s, &items[i%width]); err != nil {
b.Fatal(err)
}
}
b.StopTimer()
}
// BenchmarkEncodeCodecFromInternalProtobuf measures the cost of performing a codec encode,
// including conversions and any type setting. This is a "full" encode.
func BenchmarkEncodeCodecFromInternalProtobuf(b *testing.B) {
items := benchmarkItems(b)
width := len(items)
encodable := make([]api.Pod, width)
for i := range items {
if err := api.Scheme.Convert(&items[i], &encodable[i], nil); err != nil {
b.Fatal(err)
}
}
s := protobuf.NewSerializer(nil, nil, "application/arbitrary.content.type")
codec := api.Codecs.EncoderForVersion(s, v1.SchemeGroupVersion)
b.ResetTimer()
for i := 0; i < b.N; i++ {
if _, err := runtime.Encode(codec, &encodable[i%width]); err != nil {
b.Fatal(err)
}
}
b.StopTimer()
}
func BenchmarkEncodeProtobufGeneratedMarshal(b *testing.B) {
items := benchmarkItems(b)
width := len(items)
b.ResetTimer()
for i := 0; i < b.N; i++ {
if _, err := items[i%width].Marshal(); err != nil {
b.Fatal(err)
}
}
b.StopTimer()
}
// BenchmarkDecodeCodecToInternalProtobuf measures the cost of performing a codec decode,
// including conversions and any type setting. This is a "full" decode.
func BenchmarkDecodeCodecToInternalProtobuf(b *testing.B) {
items := benchmarkItems(b)
width := len(items)
s := protobuf.NewSerializer(api.Scheme, api.Scheme, "application/arbitrary.content.type")
encoder := api.Codecs.EncoderForVersion(s, v1.SchemeGroupVersion)
var encoded [][]byte
for i := range items {
data, err := runtime.Encode(encoder, &items[i])
if err != nil {
b.Fatal(err)
}
encoded = append(encoded, data)
}
decoder := api.Codecs.DecoderToVersion(s, api.SchemeGroupVersion)
b.ResetTimer()
for i := 0; i < b.N; i++ {
if _, err := runtime.Decode(decoder, encoded[i%width]); err != nil {
b.Fatal(err)
}
}
b.StopTimer()
}
// BenchmarkDecodeJSON provides a baseline for regular JSON decode performance
func BenchmarkDecodeIntoProtobuf(b *testing.B) {
items := benchmarkItems(b)
width := len(items)
encoded := make([][]byte, width)
for i := range items {
data, err := (&items[i]).Marshal()
if err != nil {
b.Fatal(err)
}
encoded[i] = data
validate := &v1.Pod{}
if err := proto.Unmarshal(data, validate); err != nil {
b.Fatalf("Failed to unmarshal %d: %v\n%#v", i, err, items[i])
}
}
for i := 0; i < b.N; i++ {
obj := v1.Pod{}
if err := proto.Unmarshal(encoded[i%width], &obj); err != nil {
b.Fatal(err)
}
}
}

561
vendor/k8s.io/kubernetes/pkg/api/serialization_test.go generated vendored Normal file
View file

@ -0,0 +1,561 @@
/*
Copyright 2014 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package api_test
import (
"bytes"
"encoding/hex"
"encoding/json"
"io/ioutil"
"math/rand"
"reflect"
"strings"
"testing"
"github.com/golang/protobuf/proto"
jsoniter "github.com/json-iterator/go"
"k8s.io/api/core/v1"
"k8s.io/api/extensions/v1beta1"
apiequality "k8s.io/apimachinery/pkg/api/equality"
"k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/api/testing/fuzzer"
"k8s.io/apimachinery/pkg/api/testing/roundtrip"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/conversion"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/runtime/serializer/streaming"
"k8s.io/apimachinery/pkg/util/diff"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/apimachinery/pkg/watch"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/testapi"
kapitesting "k8s.io/kubernetes/pkg/api/testing"
k8s_api_v1 "k8s.io/kubernetes/pkg/api/v1"
"k8s.io/kubernetes/pkg/apis/extensions"
k8s_v1beta1 "k8s.io/kubernetes/pkg/apis/extensions/v1beta1"
)
// fuzzInternalObject fuzzes an arbitrary runtime object using the appropriate
// fuzzer registered with the apitesting package.
func fuzzInternalObject(t *testing.T, forVersion schema.GroupVersion, item runtime.Object, seed int64) runtime.Object {
fuzzer.FuzzerFor(kapitesting.FuzzerFuncs, rand.NewSource(seed), api.Codecs).Fuzz(item)
j, err := meta.TypeAccessor(item)
if err != nil {
t.Fatalf("Unexpected error %v for %#v", err, item)
}
j.SetKind("")
j.SetAPIVersion("")
return item
}
// dataAsString returns the given byte array as a string; handles detecting
// protocol buffers.
func dataAsString(data []byte) string {
dataString := string(data)
if !strings.HasPrefix(dataString, "{") {
dataString = "\n" + hex.Dump(data)
proto.NewBuffer(make([]byte, 0, 1024)).DebugPrint("decoded object", data)
}
return dataString
}
func Convert_v1beta1_ReplicaSet_to_api_ReplicationController(in *v1beta1.ReplicaSet, out *api.ReplicationController, s conversion.Scope) error {
intermediate1 := &extensions.ReplicaSet{}
if err := k8s_v1beta1.Convert_v1beta1_ReplicaSet_To_extensions_ReplicaSet(in, intermediate1, s); err != nil {
return err
}
intermediate2 := &v1.ReplicationController{}
if err := k8s_api_v1.Convert_extensions_ReplicaSet_to_v1_ReplicationController(intermediate1, intermediate2, s); err != nil {
return err
}
return k8s_api_v1.Convert_v1_ReplicationController_To_api_ReplicationController(intermediate2, out, s)
}
func TestSetControllerConversion(t *testing.T) {
if err := api.Scheme.AddConversionFuncs(Convert_v1beta1_ReplicaSet_to_api_ReplicationController); err != nil {
t.Fatal(err)
}
rs := &extensions.ReplicaSet{}
rc := &api.ReplicationController{}
extGroup := testapi.Extensions
defaultGroup := testapi.Default
fuzzInternalObject(t, extGroup.InternalGroupVersion(), rs, rand.Int63())
t.Logf("rs._internal.extensions -> rs.v1beta1.extensions")
data, err := runtime.Encode(extGroup.Codec(), rs)
if err != nil {
t.Fatalf("unexpected encoding error: %v", err)
}
decoder := api.Codecs.DecoderToVersion(
api.Codecs.UniversalDeserializer(),
runtime.NewMultiGroupVersioner(
*defaultGroup.GroupVersion(),
schema.GroupKind{Group: defaultGroup.GroupVersion().Group},
schema.GroupKind{Group: extGroup.GroupVersion().Group},
),
)
t.Logf("rs.v1beta1.extensions -> rc._internal")
if err := runtime.DecodeInto(decoder, data, rc); err != nil {
t.Fatalf("unexpected decoding error: %v", err)
}
t.Logf("rc._internal -> rc.v1")
data, err = runtime.Encode(defaultGroup.Codec(), rc)
if err != nil {
t.Fatalf("unexpected encoding error: %v", err)
}
t.Logf("rc.v1 -> rs._internal.extensions")
if err := runtime.DecodeInto(decoder, data, rs); err != nil {
t.Fatalf("unexpected decoding error: %v", err)
}
}
// TestSpecificKind round-trips a single specific kind and is intended to help
// debug issues that arise while adding a new API type.
func TestSpecificKind(t *testing.T) {
// Uncomment the following line to enable logging of which conversions
// api.Scheme.Log(t)
internalGVK := schema.GroupVersionKind{Group: "extensions", Version: runtime.APIVersionInternal, Kind: "DaemonSet"}
seed := rand.Int63()
fuzzer := fuzzer.FuzzerFor(kapitesting.FuzzerFuncs, rand.NewSource(seed), api.Codecs)
roundtrip.RoundTripSpecificKind(t, internalGVK, api.Scheme, api.Codecs, fuzzer, nil)
}
var nonRoundTrippableTypes = sets.NewString(
"ExportOptions",
"GetOptions",
// WatchEvent does not include kind and version and can only be deserialized
// implicitly (if the caller expects the specific object). The watch call defines
// the schema by content type, rather than via kind/version included in each
// object.
"WatchEvent",
// ListOptions is now part of the meta group
"ListOptions",
// Delete options is only read in metav1
"DeleteOptions",
)
var commonKinds = []string{"Status", "ListOptions", "DeleteOptions", "ExportOptions"}
// TestCommonKindsRegistered verifies that all group/versions registered with
// the testapi package have the common kinds.
func TestCommonKindsRegistered(t *testing.T) {
for _, kind := range commonKinds {
for _, group := range testapi.Groups {
gv := group.GroupVersion()
gvk := gv.WithKind(kind)
obj, err := api.Scheme.New(gvk)
if err != nil {
t.Error(err)
}
defaults := gv.WithKind("")
var got *schema.GroupVersionKind
if obj, got, err = api.Codecs.LegacyCodec().Decode([]byte(`{"kind":"`+kind+`"}`), &defaults, obj); err != nil || gvk != *got {
t.Errorf("expected %v: %v %v", gvk, got, err)
}
data, err := runtime.Encode(api.Codecs.LegacyCodec(*gv), obj)
if err != nil {
t.Errorf("expected %v: %v\n%s", gvk, err, string(data))
continue
}
if !bytes.Contains(data, []byte(`"kind":"`+kind+`","apiVersion":"`+gv.String()+`"`)) {
if kind != "Status" {
t.Errorf("expected %v: %v\n%s", gvk, err, string(data))
continue
}
// TODO: this is wrong, but legacy clients expect it
if !bytes.Contains(data, []byte(`"kind":"`+kind+`","apiVersion":"v1"`)) {
t.Errorf("expected %v: %v\n%s", gvk, err, string(data))
continue
}
}
}
}
}
// TestRoundTripTypes applies the round-trip test to all round-trippable Kinds
// in all of the API groups registered for test in the testapi package.
func TestRoundTripTypes(t *testing.T) {
seed := rand.Int63()
fuzzer := fuzzer.FuzzerFor(kapitesting.FuzzerFuncs, rand.NewSource(seed), api.Codecs)
nonRoundTrippableTypes := map[schema.GroupVersionKind]bool{
{Group: "componentconfig", Version: runtime.APIVersionInternal, Kind: "KubeProxyConfiguration"}: true,
{Group: "componentconfig", Version: runtime.APIVersionInternal, Kind: "KubeSchedulerConfiguration"}: true,
}
roundtrip.RoundTripTypes(t, api.Scheme, api.Codecs, fuzzer, nonRoundTrippableTypes)
}
// TestEncodePtr tests that a pointer to a golang type can be encoded and
// decoded without information loss or mutation.
func TestEncodePtr(t *testing.T) {
grace := int64(30)
pod := &api.Pod{
ObjectMeta: metav1.ObjectMeta{
Labels: map[string]string{"name": "foo"},
},
Spec: api.PodSpec{
RestartPolicy: api.RestartPolicyAlways,
DNSPolicy: api.DNSClusterFirst,
TerminationGracePeriodSeconds: &grace,
SecurityContext: &api.PodSecurityContext{},
SchedulerName: api.DefaultSchedulerName,
},
}
obj := runtime.Object(pod)
data, err := runtime.Encode(testapi.Default.Codec(), obj)
obj2, err2 := runtime.Decode(testapi.Default.Codec(), data)
if err != nil || err2 != nil {
t.Fatalf("Failure: '%v' '%v'", err, err2)
}
if _, ok := obj2.(*api.Pod); !ok {
t.Fatalf("Got wrong type")
}
if !apiequality.Semantic.DeepEqual(obj2, pod) {
t.Errorf("\nExpected:\n\n %#v,\n\nGot:\n\n %#vDiff: %v\n\n", pod, obj2, diff.ObjectDiff(obj2, pod))
}
}
// TestBadJSONRejection establishes that a JSON object without a kind or with
// an unknown kind will not be decoded without error.
func TestBadJSONRejection(t *testing.T) {
badJSONMissingKind := []byte(`{ }`)
if _, err := runtime.Decode(testapi.Default.Codec(), badJSONMissingKind); err == nil {
t.Errorf("Did not reject despite lack of kind field: %s", badJSONMissingKind)
}
badJSONUnknownType := []byte(`{"kind": "bar"}`)
if _, err1 := runtime.Decode(testapi.Default.Codec(), badJSONUnknownType); err1 == nil {
t.Errorf("Did not reject despite use of unknown type: %s", badJSONUnknownType)
}
/*badJSONKindMismatch := []byte(`{"kind": "Pod"}`)
if err2 := DecodeInto(badJSONKindMismatch, &Node{}); err2 == nil {
t.Errorf("Kind is set but doesn't match the object type: %s", badJSONKindMismatch)
}*/
}
// TestUnversionedTypes establishes that the default codec can encode and
// decode unversioned objects.
func TestUnversionedTypes(t *testing.T) {
testcases := []runtime.Object{
&metav1.Status{Status: "Failure", Message: "something went wrong"},
&metav1.APIVersions{Versions: []string{"A", "B", "C"}},
&metav1.APIGroupList{Groups: []metav1.APIGroup{{Name: "mygroup"}}},
&metav1.APIGroup{Name: "mygroup"},
&metav1.APIResourceList{GroupVersion: "mygroup/myversion"},
}
for _, obj := range testcases {
// Make sure the unversioned codec can encode
unversionedJSON, err := runtime.Encode(testapi.Default.Codec(), obj)
if err != nil {
t.Errorf("%v: unexpected error: %v", obj, err)
continue
}
// Make sure the versioned codec under test can decode
versionDecodedObject, err := runtime.Decode(testapi.Default.Codec(), unversionedJSON)
if err != nil {
t.Errorf("%v: unexpected error: %v", obj, err)
continue
}
// Make sure it decodes correctly
if !reflect.DeepEqual(obj, versionDecodedObject) {
t.Errorf("%v: expected %#v, got %#v", obj, obj, versionDecodedObject)
continue
}
}
}
// TestObjectWatchFraming establishes that a watch event can be encoded and
// decoded correctly through each of the supported RFC2046 media types.
func TestObjectWatchFraming(t *testing.T) {
f := fuzzer.FuzzerFor(kapitesting.FuzzerFuncs, rand.NewSource(benchmarkSeed), api.Codecs)
secret := &api.Secret{}
f.Fuzz(secret)
secret.Data["binary"] = []byte{0x00, 0x10, 0x30, 0x55, 0xff, 0x00}
secret.Data["utf8"] = []byte("a string with \u0345 characters")
secret.Data["long"] = bytes.Repeat([]byte{0x01, 0x02, 0x03, 0x00}, 1000)
converted, _ := api.Scheme.ConvertToVersion(secret, v1.SchemeGroupVersion)
v1secret := converted.(*v1.Secret)
for _, info := range api.Codecs.SupportedMediaTypes() {
if info.StreamSerializer == nil {
continue
}
s := info.StreamSerializer
framer := s.Framer
embedded := info.Serializer
if embedded == nil {
t.Errorf("no embedded serializer for %s", info.MediaType)
continue
}
innerDecode := api.Codecs.DecoderToVersion(embedded, api.SchemeGroupVersion)
// write a single object through the framer and back out
obj := &bytes.Buffer{}
if err := s.Encode(v1secret, obj); err != nil {
t.Fatal(err)
}
out := &bytes.Buffer{}
w := framer.NewFrameWriter(out)
if n, err := w.Write(obj.Bytes()); err != nil || n != len(obj.Bytes()) {
t.Fatal(err)
}
sr := streaming.NewDecoder(framer.NewFrameReader(ioutil.NopCloser(out)), s)
resultSecret := &v1.Secret{}
res, _, err := sr.Decode(nil, resultSecret)
if err != nil {
t.Fatalf("%v:\n%s", err, hex.Dump(obj.Bytes()))
}
resultSecret.Kind = "Secret"
resultSecret.APIVersion = "v1"
if !apiequality.Semantic.DeepEqual(v1secret, res) {
t.Fatalf("objects did not match: %s", diff.ObjectGoPrintDiff(v1secret, res))
}
// write a watch event through the frame writer and read it back in
// via the frame reader for this media type
obj = &bytes.Buffer{}
if err := embedded.Encode(v1secret, obj); err != nil {
t.Fatal(err)
}
event := &metav1.WatchEvent{Type: string(watch.Added)}
event.Object.Raw = obj.Bytes()
obj = &bytes.Buffer{}
if err := s.Encode(event, obj); err != nil {
t.Fatal(err)
}
out = &bytes.Buffer{}
w = framer.NewFrameWriter(out)
if n, err := w.Write(obj.Bytes()); err != nil || n != len(obj.Bytes()) {
t.Fatal(err)
}
sr = streaming.NewDecoder(framer.NewFrameReader(ioutil.NopCloser(out)), s)
outEvent := &metav1.WatchEvent{}
res, _, err = sr.Decode(nil, outEvent)
if err != nil || outEvent.Type != string(watch.Added) {
t.Fatalf("%v: %#v", err, outEvent)
}
if outEvent.Object.Object == nil && outEvent.Object.Raw != nil {
outEvent.Object.Object, err = runtime.Decode(innerDecode, outEvent.Object.Raw)
if err != nil {
t.Fatalf("%v:\n%s", err, hex.Dump(outEvent.Object.Raw))
}
}
if !apiequality.Semantic.DeepEqual(secret, outEvent.Object.Object) {
t.Fatalf("%s: did not match after frame decoding: %s", info.MediaType, diff.ObjectGoPrintDiff(secret, outEvent.Object.Object))
}
}
}
const benchmarkSeed = 100
func benchmarkItems(b *testing.B) []v1.Pod {
apiObjectFuzzer := fuzzer.FuzzerFor(kapitesting.FuzzerFuncs, rand.NewSource(benchmarkSeed), api.Codecs)
items := make([]v1.Pod, 10)
for i := range items {
var pod api.Pod
apiObjectFuzzer.Fuzz(&pod)
pod.Spec.InitContainers, pod.Status.InitContainerStatuses = nil, nil
out, err := api.Scheme.ConvertToVersion(&pod, v1.SchemeGroupVersion)
if err != nil {
panic(err)
}
items[i] = *out.(*v1.Pod)
}
return items
}
// BenchmarkEncodeCodec measures the cost of performing a codec encode, which includes
// reflection (to clear APIVersion and Kind)
func BenchmarkEncodeCodec(b *testing.B) {
items := benchmarkItems(b)
width := len(items)
b.ResetTimer()
for i := 0; i < b.N; i++ {
if _, err := runtime.Encode(testapi.Default.Codec(), &items[i%width]); err != nil {
b.Fatal(err)
}
}
b.StopTimer()
}
// BenchmarkEncodeCodecFromInternal measures the cost of performing a codec encode,
// including conversions.
func BenchmarkEncodeCodecFromInternal(b *testing.B) {
items := benchmarkItems(b)
width := len(items)
encodable := make([]api.Pod, width)
for i := range items {
if err := api.Scheme.Convert(&items[i], &encodable[i], nil); err != nil {
b.Fatal(err)
}
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
if _, err := runtime.Encode(testapi.Default.Codec(), &encodable[i%width]); err != nil {
b.Fatal(err)
}
}
b.StopTimer()
}
// BenchmarkEncodeJSONMarshal provides a baseline for regular JSON encode performance
func BenchmarkEncodeJSONMarshal(b *testing.B) {
items := benchmarkItems(b)
width := len(items)
b.ResetTimer()
for i := 0; i < b.N; i++ {
if _, err := json.Marshal(&items[i%width]); err != nil {
b.Fatal(err)
}
}
b.StopTimer()
}
func BenchmarkDecodeCodec(b *testing.B) {
codec := testapi.Default.Codec()
items := benchmarkItems(b)
width := len(items)
encoded := make([][]byte, width)
for i := range items {
data, err := runtime.Encode(codec, &items[i])
if err != nil {
b.Fatal(err)
}
encoded[i] = data
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
if _, err := runtime.Decode(codec, encoded[i%width]); err != nil {
b.Fatal(err)
}
}
b.StopTimer()
}
func BenchmarkDecodeIntoExternalCodec(b *testing.B) {
codec := testapi.Default.Codec()
items := benchmarkItems(b)
width := len(items)
encoded := make([][]byte, width)
for i := range items {
data, err := runtime.Encode(codec, &items[i])
if err != nil {
b.Fatal(err)
}
encoded[i] = data
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
obj := v1.Pod{}
if err := runtime.DecodeInto(codec, encoded[i%width], &obj); err != nil {
b.Fatal(err)
}
}
b.StopTimer()
}
func BenchmarkDecodeIntoInternalCodec(b *testing.B) {
codec := testapi.Default.Codec()
items := benchmarkItems(b)
width := len(items)
encoded := make([][]byte, width)
for i := range items {
data, err := runtime.Encode(codec, &items[i])
if err != nil {
b.Fatal(err)
}
encoded[i] = data
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
obj := api.Pod{}
if err := runtime.DecodeInto(codec, encoded[i%width], &obj); err != nil {
b.Fatal(err)
}
}
b.StopTimer()
}
// BenchmarkDecodeJSON provides a baseline for regular JSON decode performance
func BenchmarkDecodeIntoJSON(b *testing.B) {
codec := testapi.Default.Codec()
items := benchmarkItems(b)
width := len(items)
encoded := make([][]byte, width)
for i := range items {
data, err := runtime.Encode(codec, &items[i])
if err != nil {
b.Fatal(err)
}
encoded[i] = data
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
obj := v1.Pod{}
if err := json.Unmarshal(encoded[i%width], &obj); err != nil {
b.Fatal(err)
}
}
b.StopTimer()
}
// BenchmarkDecodeJSON provides a baseline for JSON decode performance
func BenchmarkDecodeIntoJSONCodecGen(b *testing.B) {
kcodec := testapi.Default.Codec()
items := benchmarkItems(b)
width := len(items)
encoded := make([][]byte, width)
for i := range items {
data, err := runtime.Encode(kcodec, &items[i])
if err != nil {
b.Fatal(err)
}
encoded[i] = data
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
obj := v1.Pod{}
if err := jsoniter.ConfigFastest.Unmarshal(encoded[i%width], &obj); err != nil {
b.Fatal(err)
}
}
b.StopTimer()
}

View file

@ -9,7 +9,6 @@ load(
go_library(
name = "go_default_library",
srcs = ["util.go"],
importpath = "k8s.io/kubernetes/pkg/api/service",
deps = [
"//pkg/api:go_default_library",
"//pkg/util/net/sets:go_default_library",
@ -19,7 +18,6 @@ go_library(
go_test(
name = "go_default_test",
srcs = ["util_test.go"],
importpath = "k8s.io/kubernetes/pkg/api/service",
library = ":go_default_library",
deps = [
"//pkg/api:go_default_library",

View file

@ -1238,7 +1238,7 @@ type AzureDiskVolumeSource struct {
// the ReadOnly setting in VolumeMounts.
// +optional
ReadOnly *bool
// Expected values Shared: multiple blob disks per storage account Dedicated: single blob disk per storage account Managed: azure managed data disk (only in managed availability set). defaults to shared
// Expected values Shared: mulitple blob disks per storage account Dedicated: single blob disk per storage account Managed: azure managed data disk (only in managed availability set). defaults to shared
Kind *AzureDataDiskKind
}
@ -2229,7 +2229,7 @@ type Taint struct {
// TimeAdded represents the time at which the taint was added.
// It is only written for NoExecute taints.
// +optional
TimeAdded *metav1.Time
TimeAdded metav1.Time
}
type TaintEffect string
@ -3117,7 +3117,7 @@ type NodeConfigSource struct {
type DaemonEndpoint struct {
/*
The port tag was not properly in quotes in earlier releases, so it must be
uppercase for backwards compatibility (since it was falling back to var name of
uppercased for backwards compat (since it was falling back to var name of
'Port').
*/
@ -4043,7 +4043,7 @@ const (
// BasicAuthPasswordKey is the key of the password or token for SecretTypeBasicAuth secrets
BasicAuthPasswordKey = "password"
// SecretTypeSSHAuth contains data needed for SSH authentication.
// SecretTypeSSHAuth contains data needed for SSH authetication.
//
// Required field:
// - Secret.Data["ssh-privatekey"] - private SSH key needed for authentication

174
vendor/k8s.io/kubernetes/pkg/api/unstructured_test.go generated vendored Normal file
View file

@ -0,0 +1,174 @@
/*
Copyright 2017 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES 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_test
import (
"math/rand"
"reflect"
"testing"
"github.com/google/gofuzz"
"k8s.io/api/core/v1"
apiequality "k8s.io/apimachinery/pkg/api/equality"
"k8s.io/apimachinery/pkg/api/testing/fuzzer"
"k8s.io/apimachinery/pkg/conversion/unstructured"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/util/diff"
"k8s.io/apimachinery/pkg/util/json"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/testapi"
kapitesting "k8s.io/kubernetes/pkg/api/testing"
)
func doRoundTrip(t *testing.T, group testapi.TestGroup, kind string) {
// We do fuzzing on the internal version of the object, and only then
// convert to the external version. This is because custom fuzzing
// function are only supported for internal objects.
internalObj, err := api.Scheme.New(group.InternalGroupVersion().WithKind(kind))
if err != nil {
t.Fatalf("Couldn't create internal object %v: %v", kind, err)
}
seed := rand.Int63()
fuzzer.FuzzerFor(kapitesting.FuzzerFuncs, rand.NewSource(seed), api.Codecs).
// We are explicitly overwriting custom fuzzing functions, to ensure
// that InitContainers and their statuses are not generated. This is
// because in thise test we are simply doing json operations, in which
// those disappear.
Funcs(
func(s *api.PodSpec, c fuzz.Continue) {
c.FuzzNoCustom(s)
s.InitContainers = nil
},
func(s *api.PodStatus, c fuzz.Continue) {
c.FuzzNoCustom(s)
s.InitContainerStatuses = nil
},
).Fuzz(internalObj)
item, err := api.Scheme.New(group.GroupVersion().WithKind(kind))
if err != nil {
t.Fatalf("Couldn't create external object %v: %v", kind, err)
}
if err := api.Scheme.Convert(internalObj, item, nil); err != nil {
t.Fatalf("Conversion for %v failed: %v", kind, err)
}
data, err := json.Marshal(item)
if err != nil {
t.Errorf("Error when marshaling object: %v", err)
return
}
unstr := make(map[string]interface{})
err = json.Unmarshal(data, &unstr)
if err != nil {
t.Errorf("Error when unmarshaling to unstructured: %v", err)
return
}
data, err = json.Marshal(unstr)
if err != nil {
t.Errorf("Error when marshaling unstructured: %v", err)
return
}
unmarshalledObj := reflect.New(reflect.TypeOf(item).Elem()).Interface()
err = json.Unmarshal(data, &unmarshalledObj)
if err != nil {
t.Errorf("Error when unmarshaling to object: %v", err)
return
}
if !apiequality.Semantic.DeepEqual(item, unmarshalledObj) {
t.Errorf("Object changed during JSON operations, diff: %v", diff.ObjectReflectDiff(item, unmarshalledObj))
return
}
newUnstr, err := unstructured.DefaultConverter.ToUnstructured(item)
if err != nil {
t.Errorf("ToUnstructured failed: %v", err)
return
}
newObj := reflect.New(reflect.TypeOf(item).Elem()).Interface().(runtime.Object)
err = unstructured.DefaultConverter.FromUnstructured(newUnstr, newObj)
if err != nil {
t.Errorf("FromUnstructured failed: %v", err)
return
}
if !apiequality.Semantic.DeepEqual(item, newObj) {
t.Errorf("Object changed, diff: %v", diff.ObjectReflectDiff(item, newObj))
}
}
func TestRoundTrip(t *testing.T) {
for groupKey, group := range testapi.Groups {
for kind := range group.ExternalTypes() {
if nonRoundTrippableTypes.Has(kind) {
continue
}
t.Logf("Testing: %v in %v", kind, groupKey)
for i := 0; i < 50; i++ {
doRoundTrip(t, group, kind)
if t.Failed() {
break
}
}
}
}
}
func BenchmarkToFromUnstructured(b *testing.B) {
items := benchmarkItems(b)
size := len(items)
b.ResetTimer()
for i := 0; i < b.N; i++ {
unstr, err := unstructured.DefaultConverter.ToUnstructured(&items[i%size])
if err != nil {
b.Fatalf("unexpected error: %v", err)
}
obj := v1.Pod{}
if err := unstructured.DefaultConverter.FromUnstructured(unstr, &obj); err != nil {
b.Fatalf("unexpected error: %v", err)
}
}
b.StopTimer()
}
func BenchmarkToFromUnstructuredViaJSON(b *testing.B) {
items := benchmarkItems(b)
size := len(items)
b.ResetTimer()
for i := 0; i < b.N; i++ {
data, err := json.Marshal(&items[i%size])
if err != nil {
b.Fatalf("unexpected error: %v", err)
}
unstr := map[string]interface{}{}
if err := json.Unmarshal(data, &unstr); err != nil {
b.Fatalf("unexpected error: %v", err)
}
data, err = json.Marshal(unstr)
if err != nil {
b.Fatalf("unexpected error: %v", err)
}
obj := v1.Pod{}
if err := json.Unmarshal(data, &obj); err != nil {
b.Fatalf("unexpected error: %v", err)
}
}
b.StopTimer()
}

31
vendor/k8s.io/kubernetes/pkg/api/util/BUILD generated vendored Normal file
View file

@ -0,0 +1,31 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
"go_test",
)
go_library(
name = "go_default_library",
srcs = ["group_version.go"],
)
go_test(
name = "go_default_test",
srcs = ["group_version_test.go"],
library = ":go_default_library",
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
)

3
vendor/k8s.io/kubernetes/pkg/api/util/OWNERS generated vendored Executable file
View file

@ -0,0 +1,3 @@
reviewers:
- caesarxuchao
- david-mcmahon

48
vendor/k8s.io/kubernetes/pkg/api/util/group_version.go generated vendored Normal file
View file

@ -0,0 +1,48 @@
/*
Copyright 2015 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// TODO: This GetVersion/GetGroup arrangement is temporary and will be replaced
// with a GroupAndVersion type.
package util
import "strings"
func GetVersion(groupVersion string) string {
s := strings.Split(groupVersion, "/")
if len(s) != 2 {
// e.g. return "v1" for groupVersion="v1"
return s[len(s)-1]
}
return s[1]
}
func GetGroup(groupVersion string) string {
s := strings.Split(groupVersion, "/")
if len(s) == 1 {
// e.g. return "" for groupVersion="v1"
return ""
}
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
}

View file

@ -0,0 +1,93 @@
/*
Copyright 2014 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package util
import "testing"
func TestGetVersion(t *testing.T) {
testCases := []struct {
groupVersion string
output string
}{
{
"v1",
"v1",
},
{
"extensions/v1beta1",
"v1beta1",
},
}
for _, test := range testCases {
actual := GetVersion(test.groupVersion)
if test.output != actual {
t.Errorf("expect version: %s, got: %s\n", test.output, actual)
}
}
}
func TestGetGroup(t *testing.T) {
testCases := []struct {
groupVersion string
output string
}{
{
"v1",
"",
},
{
"extensions/v1beta1",
"extensions",
},
}
for _, test := range testCases {
actual := GetGroup(test.groupVersion)
if test.output != actual {
t.Errorf("expect version: %s, got: %s\n", test.output, actual)
}
}
}
func TestGetGroupVersion(t *testing.T) {
testCases := []struct {
group string
version string
output string
}{
{
"",
"v1",
"v1",
},
{
"extensions",
"",
"extensions/",
},
{
"extensions",
"v1beta1",
"extensions/v1beta1",
},
}
for _, test := range testCases {
actual := GetGroupVersion(test.group, test.version)
if test.output != actual {
t.Errorf("expect version: %s, got: %s\n", test.output, actual)
}
}
}

View file

@ -12,11 +12,11 @@ go_library(
"conversion.go",
"defaults.go",
"doc.go",
"generate.go",
"register.go",
"zz_generated.conversion.go",
"zz_generated.defaults.go",
],
importpath = "k8s.io/kubernetes/pkg/api/v1",
deps = [
"//pkg/api:go_default_library",
"//pkg/apis/extensions:go_default_library",
@ -30,6 +30,7 @@ go_library(
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/types:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/intstr:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/rand:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/validation/field:go_default_library",
],
)
@ -37,14 +38,16 @@ go_library(
go_test(
name = "go_default_xtest",
srcs = [
"backward_compatibility_test.go",
"conversion_test.go",
"defaults_test.go",
],
importpath = "k8s.io/kubernetes/pkg/api/v1_test",
deps = [
":go_default_library",
"//pkg/api:go_default_library",
"//pkg/api/testapi:go_default_library",
"//pkg/api/install:go_default_library",
"//pkg/api/testing/compat:go_default_library",
"//pkg/api/validation:go_default_library",
"//vendor/k8s.io/api/core/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/equality:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/resource:go_default_library",
@ -52,6 +55,7 @@ go_test(
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/diff:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/intstr:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/validation/field:go_default_library",
],
)

View file

@ -0,0 +1,169 @@
/*
Copyright 2015 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package v1_test
import (
"testing"
"k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/util/validation/field"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/testing/compat"
"k8s.io/kubernetes/pkg/api/validation"
_ "k8s.io/kubernetes/pkg/api/install"
)
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) field.ErrorList {
return validation.ValidatePodSpec(&(obj.(*api.Pod).Spec), field.NewPath("spec"))
}
for _, tc := range cases {
t.Logf("Testing 1.0.0 backward compatibility for %v", tc.name)
compat.TestCompatibility(t, v1.SchemeGroupVersion, []byte(tc.input), validator, tc.expectedKeys, tc.absentKeys)
}
}

View file

@ -30,9 +30,6 @@ import (
"k8s.io/apimachinery/pkg/util/diff"
"k8s.io/kubernetes/pkg/api"
k8s_api_v1 "k8s.io/kubernetes/pkg/api/v1"
// enforce that all types are installed
_ "k8s.io/kubernetes/pkg/api/testapi"
)
func TestPodLogOptions(t *testing.T) {

View file

@ -28,9 +28,6 @@ import (
"k8s.io/apimachinery/pkg/util/intstr"
"k8s.io/kubernetes/pkg/api"
k8s_api_v1 "k8s.io/kubernetes/pkg/api/v1"
// enforce that all types are installed
_ "k8s.io/kubernetes/pkg/api/testapi"
)
func roundTrip(t *testing.T, obj runtime.Object) runtime.Object {

65
vendor/k8s.io/kubernetes/pkg/api/v1/generate.go generated vendored Normal file
View file

@ -0,0 +1,65 @@
/*
Copyright 2014 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package v1
import (
"fmt"
"k8s.io/api/core/v1"
utilrand "k8s.io/apimachinery/pkg/util/rand"
)
// NameGenerator generates names for objects. Some backends may have more information
// available to guide selection of new names and this interface hides those details.
type NameGenerator interface {
// GenerateName generates a valid name from the base name, adding a random suffix to the
// the base. If base is valid, the returned name must also be valid. The generator is
// responsible for knowing the maximum valid name length.
GenerateName(base string) string
}
// GenerateName will resolve the object name of the provided v1.ObjectMeta to a generated version if
// necessary. It expects that validation for v1.ObjectMeta has already completed (that Base is a
// valid name) and that the NameGenerator generates a name that is also valid.
func GenerateName(u NameGenerator, meta *v1.ObjectMeta) {
if len(meta.GenerateName) == 0 || len(meta.Name) != 0 {
return
}
meta.Name = u.GenerateName(meta.GenerateName)
}
// simpleNameGenerator generates random names.
type simpleNameGenerator struct{}
// SimpleNameGenerator is a generator that returns the name plus a random suffix of five alphanumerics
// when a name is requested. The string is guaranteed to not exceed the length of a standard Kubernetes
// name (63 characters)
var SimpleNameGenerator NameGenerator = simpleNameGenerator{}
const (
// TODO: make this flexible for non-core resources with alternate naming rules.
maxNameLength = 63
randomLength = 5
maxGeneratedNameLength = maxNameLength - randomLength
)
func (simpleNameGenerator) GenerateName(base string) string {
if len(base) > maxGeneratedNameLength {
base = base[:maxGeneratedNameLength]
}
return fmt.Sprintf("%s%s", base, utilrand.String(randomLength))
}

View file

@ -9,7 +9,6 @@ load(
go_test(
name = "go_default_test",
srcs = ["helpers_test.go"],
importpath = "k8s.io/kubernetes/pkg/api/v1/helper",
library = ":go_default_library",
deps = [
"//vendor/k8s.io/api/core/v1:go_default_library",
@ -22,7 +21,6 @@ go_test(
go_library(
name = "go_default_library",
srcs = ["helpers.go"],
importpath = "k8s.io/kubernetes/pkg/api/v1/helper",
deps = [
"//pkg/api/helper:go_default_library",
"//vendor/k8s.io/api/core/v1:go_default_library",

View file

@ -88,18 +88,12 @@ func OpaqueIntResourceName(name string) v1.ResourceName {
var overcommitBlacklist = sets.NewString(string(v1.ResourceNvidiaGPU))
// IsOvercommitAllowed returns true if the resource is in the default
// namespace and not blacklisted and is not hugepages.
// namespace and not blacklisted.
func IsOvercommitAllowed(name v1.ResourceName) bool {
return IsDefaultNamespaceResource(name) &&
!IsHugePageResourceName(name) &&
!overcommitBlacklist.Has(string(name))
}
// Extended and Hugepages resources
func IsScalarResourceName(name v1.ResourceName) bool {
return IsExtendedResourceName(name) || IsHugePageResourceName(name)
}
// this function aims to check if the service's ClusterIP is set or not
// the objective is not to perform validation here
func IsServiceIPSet(service *v1.Service) bool {

View file

@ -9,7 +9,6 @@ load(
go_library(
name = "go_default_library",
srcs = ["util.go"],
importpath = "k8s.io/kubernetes/pkg/api/v1/pod",
deps = [
"//vendor/k8s.io/api/core/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
@ -20,7 +19,6 @@ go_library(
go_test(
name = "go_default_test",
srcs = ["util_test.go"],
importpath = "k8s.io/kubernetes/pkg/api/v1/pod",
library = ":go_default_library",
deps = [
"//vendor/k8s.io/api/core/v1:go_default_library",

View file

@ -5101,7 +5101,7 @@ func autoConvert_v1_Taint_To_api_Taint(in *v1.Taint, out *api.Taint, s conversio
out.Key = in.Key
out.Value = in.Value
out.Effect = api.TaintEffect(in.Effect)
out.TimeAdded = (*meta_v1.Time)(unsafe.Pointer(in.TimeAdded))
out.TimeAdded = in.TimeAdded
return nil
}
@ -5114,7 +5114,7 @@ func autoConvert_api_Taint_To_v1_Taint(in *api.Taint, out *v1.Taint, s conversio
out.Key = in.Key
out.Value = in.Value
out.Effect = v1.TaintEffect(in.Effect)
out.TimeAdded = (*meta_v1.Time)(unsafe.Pointer(in.TimeAdded))
out.TimeAdded = in.TimeAdded
return nil
}

View file

@ -11,12 +11,12 @@ go_library(
"events.go",
"validation.go",
],
importpath = "k8s.io/kubernetes/pkg/api/validation",
visibility = ["//visibility:public"],
deps = [
"//pkg/api:go_default_library",
"//pkg/api/helper:go_default_library",
"//pkg/api/service:go_default_library",
"//pkg/api/util:go_default_library",
"//pkg/api/v1:go_default_library",
"//pkg/api/v1/helper:go_default_library",
"//pkg/capabilities:go_default_library",
@ -47,7 +47,6 @@ go_test(
"events_test.go",
"validation_test.go",
],
importpath = "k8s.io/kubernetes/pkg/api/validation",
library = ":go_default_library",
deps = [
"//pkg/api:go_default_library",

View file

@ -25,6 +25,7 @@ import (
"k8s.io/apimachinery/pkg/util/validation"
"k8s.io/apimachinery/pkg/util/validation/field"
"k8s.io/kubernetes/pkg/api"
apiutil "k8s.io/kubernetes/pkg/api/util"
)
// ValidateEvent makes sure that the event makes sense.
@ -62,16 +63,12 @@ func ValidateEvent(event *api.Event) field.ErrorList {
// Check whether the kind in groupVersion is scoped at the root of the api hierarchy
func isNamespacedKind(kind, groupVersion string) (bool, error) {
gv, err := schema.ParseGroupVersion(groupVersion)
group := apiutil.GetGroup(groupVersion)
g, err := api.Registry.Group(group)
if err != nil {
return false, err
}
g, err := api.Registry.Group(gv.Group)
if err != nil {
return false, err
}
restMapping, err := g.RESTMapper.RESTMapping(schema.GroupKind{Group: gv.Group, Kind: kind}, gv.Version)
restMapping, err := g.RESTMapper.RESTMapping(schema.GroupKind{Group: group, Kind: kind}, apiutil.GetVersion(groupVersion))
if err != nil {
return false, err
}

View file

@ -1923,7 +1923,11 @@ func ValidateVolumeMounts(mounts []api.VolumeMount, volumes sets.String, contain
allErrs = append(allErrs, field.Invalid(idxPath.Child("mountPath"), mnt.MountPath, "must be unique"))
}
if !path.IsAbs(mnt.MountPath) {
allErrs = append(allErrs, field.Invalid(idxPath.Child("mountPath"), mnt.MountPath, "must be an absolute path"))
// also allow windows absolute path
p := mnt.MountPath
if len(p) < 2 || ((p[0] < 'A' || p[0] > 'Z') && (p[0] < 'a' || p[0] > 'z')) || p[1] != ':' {
allErrs = append(allErrs, field.Invalid(idxPath.Child("mountPath"), mnt.MountPath, "must be an absolute path"))
}
}
mountpoints.Insert(mnt.MountPath)
if len(mnt.SubPath) > 0 {
@ -3148,22 +3152,6 @@ func ValidateService(service *api.Service) field.ErrorList {
ports[key] = true
}
// Check for duplicate TargetPort
portsPath = specPath.Child("ports")
targetPorts := make(map[api.ServicePort]bool)
for i, port := range service.Spec.Ports {
if (port.TargetPort.Type == intstr.Int && port.TargetPort.IntVal == 0) || (port.TargetPort.Type == intstr.String && port.TargetPort.StrVal == "") {
continue
}
portPath := portsPath.Index(i)
key := api.ServicePort{Protocol: port.Protocol, TargetPort: port.TargetPort}
_, found := targetPorts[key]
if found {
allErrs = append(allErrs, field.Duplicate(portPath.Child("targetPort"), port.TargetPort))
}
targetPorts[key] = true
}
// Validate SourceRange field and annotation
_, ok := service.Annotations[api.AnnotationLoadBalancerSourceRangesKey]
if len(service.Spec.LoadBalancerSourceRanges) > 0 || ok {

View file

@ -3059,12 +3059,12 @@ func TestValidatePorts(t *testing.T) {
"invalid protocol case": {
[]api.ContainerPort{{ContainerPort: 80, Protocol: "tcp"}},
field.ErrorTypeNotSupported,
"protocol", `supported values: "TCP", "UDP"`,
"protocol", "supported values: TCP, UDP",
},
"invalid protocol": {
[]api.ContainerPort{{ContainerPort: 80, Protocol: "ICMP"}},
field.ErrorTypeNotSupported,
"protocol", `supported values: "TCP", "UDP"`,
"protocol", "supported values: TCP, UDP",
},
"protocol required": {
[]api.ContainerPort{{Name: "abc", ContainerPort: 80}},
@ -3426,7 +3426,7 @@ func TestValidateEnv(t *testing.T) {
},
},
}},
expectedError: `[0].valueFrom.fieldRef.fieldPath: Unsupported value: "metadata.labels": supported values: "metadata.name", "metadata.namespace", "metadata.uid", "spec.nodeName", "spec.serviceAccountName", "status.hostIP", "status.podIP"`,
expectedError: `[0].valueFrom.fieldRef.fieldPath: Unsupported value: "metadata.labels": supported values: metadata.name, metadata.namespace, metadata.uid, spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP`,
},
{
name: "invalid fieldPath annotations",
@ -3439,7 +3439,7 @@ func TestValidateEnv(t *testing.T) {
},
},
}},
expectedError: `[0].valueFrom.fieldRef.fieldPath: Unsupported value: "metadata.annotations": supported values: "metadata.name", "metadata.namespace", "metadata.uid", "spec.nodeName", "spec.serviceAccountName", "status.hostIP", "status.podIP"`,
expectedError: `[0].valueFrom.fieldRef.fieldPath: Unsupported value: "metadata.annotations": supported values: metadata.name, metadata.namespace, metadata.uid, spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP`,
},
{
name: "unsupported fieldPath",
@ -3452,7 +3452,7 @@ func TestValidateEnv(t *testing.T) {
},
},
}},
expectedError: `valueFrom.fieldRef.fieldPath: Unsupported value: "status.phase": supported values: "metadata.name", "metadata.namespace", "metadata.uid", "spec.nodeName", "spec.serviceAccountName", "status.hostIP", "status.podIP"`,
expectedError: `valueFrom.fieldRef.fieldPath: Unsupported value: "status.phase": supported values: metadata.name, metadata.namespace, metadata.uid, spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP`,
},
}
for _, tc := range errorCases {
@ -5036,7 +5036,7 @@ func TestValidatePod(t *testing.T) {
Name: "pod-forgiveness-invalid",
Namespace: "ns",
},
Spec: extendPodSpecwithTolerations(validPodSpec(nil), []api.Toleration{{Key: "node.kubernetes.io/not-ready", Operator: "Exists", Effect: "NoExecute", TolerationSeconds: &[]int64{-2}[0]}}),
Spec: extendPodSpecwithTolerations(validPodSpec(nil), []api.Toleration{{Key: "node.alpha.kubernetes.io/notReady", Operator: "Exists", Effect: "NoExecute", TolerationSeconds: &[]int64{-2}[0]}}),
},
{ // docker default seccomp profile
ObjectMeta: metav1.ObjectMeta{
@ -5594,7 +5594,7 @@ func TestValidatePod(t *testing.T) {
Name: "pod-forgiveness-invalid",
Namespace: "ns",
},
Spec: extendPodSpecwithTolerations(validPodSpec(nil), []api.Toleration{{Key: "node.kubernetes.io/not-ready", Operator: "Exists", Effect: "NoSchedule", TolerationSeconds: &[]int64{20}[0]}}),
Spec: extendPodSpecwithTolerations(validPodSpec(nil), []api.Toleration{{Key: "node.alpha.kubernetes.io/notReady", Operator: "Exists", Effect: "NoSchedule", TolerationSeconds: &[]int64{20}[0]}}),
},
},
"must be a valid pod seccomp profile": {
@ -7050,42 +7050,6 @@ func TestValidateService(t *testing.T) {
},
numErrs: 0,
},
{
name: "invalid duplicate targetports (number with same protocol)",
tweakSvc: func(s *api.Service) {
s.Spec.Type = api.ServiceTypeClusterIP
s.Spec.Ports = append(s.Spec.Ports, api.ServicePort{Name: "q", Port: 1, Protocol: "TCP", TargetPort: intstr.FromInt(8080)})
s.Spec.Ports = append(s.Spec.Ports, api.ServicePort{Name: "r", Port: 2, Protocol: "TCP", TargetPort: intstr.FromInt(8080)})
},
numErrs: 1,
},
{
name: "invalid duplicate targetports (name with same protocol)",
tweakSvc: func(s *api.Service) {
s.Spec.Type = api.ServiceTypeClusterIP
s.Spec.Ports = append(s.Spec.Ports, api.ServicePort{Name: "q", Port: 1, Protocol: "TCP", TargetPort: intstr.FromString("http")})
s.Spec.Ports = append(s.Spec.Ports, api.ServicePort{Name: "r", Port: 2, Protocol: "TCP", TargetPort: intstr.FromString("http")})
},
numErrs: 1,
},
{
name: "valid duplicate targetports (number with different protocols)",
tweakSvc: func(s *api.Service) {
s.Spec.Type = api.ServiceTypeClusterIP
s.Spec.Ports = append(s.Spec.Ports, api.ServicePort{Name: "q", Port: 1, Protocol: "TCP", TargetPort: intstr.FromInt(8080)})
s.Spec.Ports = append(s.Spec.Ports, api.ServicePort{Name: "r", Port: 2, Protocol: "UDP", TargetPort: intstr.FromInt(8080)})
},
numErrs: 0,
},
{
name: "valid duplicate targetports (name with different protocols)",
tweakSvc: func(s *api.Service) {
s.Spec.Type = api.ServiceTypeClusterIP
s.Spec.Ports = append(s.Spec.Ports, api.ServicePort{Name: "q", Port: 1, Protocol: "TCP", TargetPort: intstr.FromString("http")})
s.Spec.Ports = append(s.Spec.Ports, api.ServicePort{Name: "r", Port: 2, Protocol: "UDP", TargetPort: intstr.FromString("http")})
},
numErrs: 0,
},
{
name: "valid type - cluster",
tweakSvc: func(s *api.Service) {

View file

@ -5903,15 +5903,7 @@ func (in *TCPSocketAction) DeepCopy() *TCPSocketAction {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Taint) DeepCopyInto(out *Taint) {
*out = *in
if in.TimeAdded != nil {
in, out := &in.TimeAdded, &out.TimeAdded
if *in == nil {
*out = nil
} else {
*out = new(v1.Time)
(*in).DeepCopyInto(*out)
}
}
in.TimeAdded.DeepCopyInto(&out.TimeAdded)
return
}