Update go dependencies and cleanup deprecated packages
This commit is contained in:
parent
03a1e20fde
commit
44fd79d061
1099 changed files with 75691 additions and 31913 deletions
116
vendor/k8s.io/kubernetes/pkg/api/BUILD
generated
vendored
116
vendor/k8s.io/kubernetes/pkg/api/BUILD
generated
vendored
|
|
@ -1,116 +0,0 @@
|
|||
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"annotation_key_constants.go",
|
||||
"doc.go",
|
||||
"field_constants.go",
|
||||
"json.go",
|
||||
"objectreference.go",
|
||||
"register.go",
|
||||
"resource.go",
|
||||
"taint.go",
|
||||
"toleration.go",
|
||||
"types.go",
|
||||
"zz_generated.deepcopy.go",
|
||||
],
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/resource:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apimachinery/announced:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apimachinery/registered:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/internalversion:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/conversion:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/fields:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/labels: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:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/types:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/intstr:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["taint_test.go"],
|
||||
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(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [
|
||||
":package-srcs",
|
||||
"//pkg/api/endpoints:all-srcs",
|
||||
"//pkg/api/events:all-srcs",
|
||||
"//pkg/api/fuzzer:all-srcs",
|
||||
"//pkg/api/helper:all-srcs",
|
||||
"//pkg/api/install:all-srcs",
|
||||
"//pkg/api/persistentvolume:all-srcs",
|
||||
"//pkg/api/pod:all-srcs",
|
||||
"//pkg/api/ref:all-srcs",
|
||||
"//pkg/api/resource:all-srcs",
|
||||
"//pkg/api/service:all-srcs",
|
||||
"//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",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
44
vendor/k8s.io/kubernetes/pkg/api/OWNERS
generated
vendored
44
vendor/k8s.io/kubernetes/pkg/api/OWNERS
generated
vendored
|
|
@ -1,44 +1,4 @@
|
|||
approvers:
|
||||
- erictune
|
||||
- lavalamp
|
||||
- smarterclayton
|
||||
- thockin
|
||||
- liggitt
|
||||
# - bgrant0607 # manual escalations only
|
||||
- api-approvers
|
||||
reviewers:
|
||||
- thockin
|
||||
- lavalamp
|
||||
- smarterclayton
|
||||
- wojtek-t
|
||||
- deads2k
|
||||
- yujuhong
|
||||
- brendandburns
|
||||
- derekwaynecarr
|
||||
- caesarxuchao
|
||||
- vishh
|
||||
- mikedanese
|
||||
- liggitt
|
||||
- nikhiljindal
|
||||
- gmarek
|
||||
- erictune
|
||||
- davidopp
|
||||
- pmorie
|
||||
- sttts
|
||||
- dchen1107
|
||||
- saad-ali
|
||||
- zmerlynn
|
||||
- luxas
|
||||
- janetkuo
|
||||
- justinsb
|
||||
- pwittrock
|
||||
- roberthbailey
|
||||
- ncdc
|
||||
- tallclair
|
||||
- yifan-gu
|
||||
- eparis
|
||||
- mwielgus
|
||||
- timothysc
|
||||
- soltysh
|
||||
- piosz
|
||||
- jsafrane
|
||||
- jbeda
|
||||
- api-reviewers
|
||||
|
|
|
|||
94
vendor/k8s.io/kubernetes/pkg/api/annotation_key_constants.go
generated
vendored
94
vendor/k8s.io/kubernetes/pkg/api/annotation_key_constants.go
generated
vendored
|
|
@ -1,94 +0,0 @@
|
|||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
// This file should be consistent with pkg/api/v1/annotation_key_constants.go.
|
||||
|
||||
package api
|
||||
|
||||
const (
|
||||
// ImagePolicyFailedOpenKey is added to pods created by failing open when the image policy
|
||||
// webhook backend fails.
|
||||
ImagePolicyFailedOpenKey string = "alpha.image-policy.k8s.io/failed-open"
|
||||
|
||||
// PodPresetOptOutAnnotationKey represents the annotation key for a pod to exempt itself from pod preset manipulation
|
||||
PodPresetOptOutAnnotationKey string = "podpreset.admission.kubernetes.io/exclude"
|
||||
|
||||
// MirrorAnnotationKey represents the annotation key set by kubelets when creating mirror pods
|
||||
MirrorPodAnnotationKey string = "kubernetes.io/config.mirror"
|
||||
|
||||
// TolerationsAnnotationKey represents the key of tolerations data (json serialized)
|
||||
// in the Annotations of a Pod.
|
||||
TolerationsAnnotationKey string = "scheduler.alpha.kubernetes.io/tolerations"
|
||||
|
||||
// TaintsAnnotationKey represents the key of taints data (json serialized)
|
||||
// in the Annotations of a Node.
|
||||
TaintsAnnotationKey string = "scheduler.alpha.kubernetes.io/taints"
|
||||
|
||||
// SeccompPodAnnotationKey represents the key of a seccomp profile applied
|
||||
// to all containers of a pod.
|
||||
SeccompPodAnnotationKey string = "seccomp.security.alpha.kubernetes.io/pod"
|
||||
|
||||
// SeccompContainerAnnotationKeyPrefix represents the key of a seccomp profile applied
|
||||
// to one container of a pod.
|
||||
SeccompContainerAnnotationKeyPrefix string = "container.seccomp.security.alpha.kubernetes.io/"
|
||||
|
||||
// CreatedByAnnotation represents the key used to store the spec(json)
|
||||
// used to create the resource.
|
||||
// This field is deprecated in favor of ControllerRef (see #44407).
|
||||
// TODO(#50720): Remove this field in v1.9.
|
||||
CreatedByAnnotation = "kubernetes.io/created-by"
|
||||
|
||||
// PreferAvoidPodsAnnotationKey represents the key of preferAvoidPods data (json serialized)
|
||||
// in the Annotations of a Node.
|
||||
PreferAvoidPodsAnnotationKey string = "scheduler.alpha.kubernetes.io/preferAvoidPods"
|
||||
|
||||
// SysctlsPodAnnotationKey represents the key of sysctls which are set for the infrastructure
|
||||
// container of a pod. The annotation value is a comma separated list of sysctl_name=value
|
||||
// key-value pairs. Only a limited set of whitelisted and isolated sysctls is supported by
|
||||
// the kubelet. Pods with other sysctls will fail to launch.
|
||||
SysctlsPodAnnotationKey string = "security.alpha.kubernetes.io/sysctls"
|
||||
|
||||
// UnsafeSysctlsPodAnnotationKey represents the key of sysctls which are set for the infrastructure
|
||||
// container of a pod. The annotation value is a comma separated list of sysctl_name=value
|
||||
// key-value pairs. Unsafe sysctls must be explicitly enabled for a kubelet. They are properly
|
||||
// namespaced to a pod or a container, but their isolation is usually unclear or weak. Their use
|
||||
// is at-your-own-risk. Pods that attempt to set an unsafe sysctl that is not enabled for a kubelet
|
||||
// will fail to launch.
|
||||
UnsafeSysctlsPodAnnotationKey string = "security.alpha.kubernetes.io/unsafe-sysctls"
|
||||
|
||||
// ObjectTTLAnnotations represents a suggestion for kubelet for how long it can cache
|
||||
// an object (e.g. secret, config map) before fetching it again from apiserver.
|
||||
// This annotation can be attached to node.
|
||||
ObjectTTLAnnotationKey string = "node.alpha.kubernetes.io/ttl"
|
||||
|
||||
// annotation key prefix used to identify non-convertible json paths.
|
||||
NonConvertibleAnnotationPrefix = "non-convertible.kubernetes.io"
|
||||
|
||||
kubectlPrefix = "kubectl.kubernetes.io/"
|
||||
|
||||
// LastAppliedConfigAnnotation is the annotation used to store the previous
|
||||
// configuration of a resource for use in a three way diff by UpdateApplyAnnotation.
|
||||
LastAppliedConfigAnnotation = kubectlPrefix + "last-applied-configuration"
|
||||
|
||||
// AnnotationLoadBalancerSourceRangesKey is the key of the annotation on a service to set allowed ingress ranges on their LoadBalancers
|
||||
//
|
||||
// It should be a comma-separated list of CIDRs, e.g. `0.0.0.0/0` to
|
||||
// allow full access (the default) or `18.0.0.0/8,56.0.0.0/8` to allow
|
||||
// access only from the CIDRs currently allocated to MIT & the USPS.
|
||||
//
|
||||
// Not all cloud providers support this annotation, though AWS & GCE do.
|
||||
AnnotationLoadBalancerSourceRangesKey = "service.beta.kubernetes.io/load-balancer-source-ranges"
|
||||
)
|
||||
117
vendor/k8s.io/kubernetes/pkg/api/conversion_test.go
generated
vendored
117
vendor/k8s.io/kubernetes/pkg/api/conversion_test.go
generated
vendored
|
|
@ -1,117 +0,0 @@
|
|||
/*
|
||||
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
87
vendor/k8s.io/kubernetes/pkg/api/copy_test.go
generated
vendored
|
|
@ -1,87 +0,0 @@
|
|||
/*
|
||||
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
177
vendor/k8s.io/kubernetes/pkg/api/deep_copy_test.go
generated
vendored
|
|
@ -1,177 +0,0 @@
|
|||
/*
|
||||
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
225
vendor/k8s.io/kubernetes/pkg/api/defaulting_test.go
generated
vendored
|
|
@ -1,225 +0,0 @@
|
|||
/*
|
||||
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()
|
||||
}
|
||||
24
vendor/k8s.io/kubernetes/pkg/api/doc.go
generated
vendored
24
vendor/k8s.io/kubernetes/pkg/api/doc.go
generated
vendored
|
|
@ -1,24 +0,0 @@
|
|||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
// +k8s:deepcopy-gen=package,register
|
||||
|
||||
// Package api contains the latest (or "internal") version of the
|
||||
// Kubernetes API objects. This is the API objects as represented in memory.
|
||||
// The contract presented to clients is located in the versioned packages,
|
||||
// which are sub-directories. The first one is "v1". Those packages
|
||||
// describe how a particular version is serialized to storage/network.
|
||||
package api // import "k8s.io/kubernetes/pkg/api"
|
||||
38
vendor/k8s.io/kubernetes/pkg/api/field_constants.go
generated
vendored
38
vendor/k8s.io/kubernetes/pkg/api/field_constants.go
generated
vendored
|
|
@ -1,38 +0,0 @@
|
|||
/*
|
||||
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
|
||||
|
||||
// Field path constants that are specific to the internal API
|
||||
// representation.
|
||||
const (
|
||||
NodeUnschedulableField = "spec.unschedulable"
|
||||
ObjectNameField = "metadata.name"
|
||||
PodHostField = "spec.nodeName"
|
||||
PodStatusField = "status.phase"
|
||||
SecretTypeField = "type"
|
||||
|
||||
EventReasonField = "reason"
|
||||
EventSourceField = "source"
|
||||
EventTypeField = "type"
|
||||
EventInvolvedKindField = "involvedObject.kind"
|
||||
EventInvolvedNamespaceField = "involvedObject.namespace"
|
||||
EventInvolvedNameField = "involvedObject.name"
|
||||
EventInvolvedUIDField = "involvedObject.uid"
|
||||
EventInvolvedAPIVersionField = "involvedObject.apiVersion"
|
||||
EventInvolvedResourceVersionField = "involvedObject.resourceVersion"
|
||||
EventInvolvedFieldPathField = "involvedObject.fieldPath"
|
||||
)
|
||||
49
vendor/k8s.io/kubernetes/pkg/api/helper/BUILD
generated
vendored
49
vendor/k8s.io/kubernetes/pkg/api/helper/BUILD
generated
vendored
|
|
@ -1,49 +0,0 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
"go_test",
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["helpers_test.go"],
|
||||
library = ":go_default_library",
|
||||
deps = [
|
||||
"//pkg/api:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/resource:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/labels:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["helpers.go"],
|
||||
deps = [
|
||||
"//pkg/api:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/resource: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/fields:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/labels:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/selection:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [
|
||||
":package-srcs",
|
||||
"//pkg/api/helper/qos:all-srcs",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
650
vendor/k8s.io/kubernetes/pkg/api/helper/helpers.go
generated
vendored
650
vendor/k8s.io/kubernetes/pkg/api/helper/helpers.go
generated
vendored
|
|
@ -1,650 +0,0 @@
|
|||
/*
|
||||
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 helper
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/conversion"
|
||||
"k8s.io/apimachinery/pkg/fields"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/apimachinery/pkg/selection"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
)
|
||||
|
||||
// IsHugePageResourceName returns true if the resource name has the huge page
|
||||
// resource prefix.
|
||||
func IsHugePageResourceName(name api.ResourceName) bool {
|
||||
return strings.HasPrefix(string(name), api.ResourceHugePagesPrefix)
|
||||
}
|
||||
|
||||
// HugePageResourceName returns a ResourceName with the canonical hugepage
|
||||
// prefix prepended for the specified page size. The page size is converted
|
||||
// to its canonical representation.
|
||||
func HugePageResourceName(pageSize resource.Quantity) api.ResourceName {
|
||||
return api.ResourceName(fmt.Sprintf("%s%s", api.ResourceHugePagesPrefix, pageSize.String()))
|
||||
}
|
||||
|
||||
// HugePageSizeFromResourceName returns the page size for the specified huge page
|
||||
// resource name. If the specified input is not a valid huge page resource name
|
||||
// an error is returned.
|
||||
func HugePageSizeFromResourceName(name api.ResourceName) (resource.Quantity, error) {
|
||||
if !IsHugePageResourceName(name) {
|
||||
return resource.Quantity{}, fmt.Errorf("resource name: %s is not valid hugepage name", name)
|
||||
}
|
||||
pageSize := strings.TrimPrefix(string(name), api.ResourceHugePagesPrefix)
|
||||
return resource.ParseQuantity(pageSize)
|
||||
}
|
||||
|
||||
// NonConvertibleFields iterates over the provided map and filters out all but
|
||||
// any keys with the "non-convertible.kubernetes.io" prefix.
|
||||
func NonConvertibleFields(annotations map[string]string) map[string]string {
|
||||
nonConvertibleKeys := map[string]string{}
|
||||
for key, value := range annotations {
|
||||
if strings.HasPrefix(key, api.NonConvertibleAnnotationPrefix) {
|
||||
nonConvertibleKeys[key] = value
|
||||
}
|
||||
}
|
||||
return nonConvertibleKeys
|
||||
}
|
||||
|
||||
// Semantic can do semantic deep equality checks for api objects.
|
||||
// Example: apiequality.Semantic.DeepEqual(aPod, aPodWithNonNilButEmptyMaps) == true
|
||||
var Semantic = conversion.EqualitiesOrDie(
|
||||
func(a, b resource.Quantity) bool {
|
||||
// Ignore formatting, only care that numeric value stayed the same.
|
||||
// TODO: if we decide it's important, it should be safe to start comparing the format.
|
||||
//
|
||||
// Uninitialized quantities are equivalent to 0 quantities.
|
||||
return a.Cmp(b) == 0
|
||||
},
|
||||
func(a, b metav1.MicroTime) bool {
|
||||
return a.UTC() == b.UTC()
|
||||
},
|
||||
func(a, b metav1.Time) bool {
|
||||
return a.UTC() == b.UTC()
|
||||
},
|
||||
func(a, b labels.Selector) bool {
|
||||
return a.String() == b.String()
|
||||
},
|
||||
func(a, b fields.Selector) bool {
|
||||
return a.String() == b.String()
|
||||
},
|
||||
)
|
||||
|
||||
var standardResourceQuotaScopes = sets.NewString(
|
||||
string(api.ResourceQuotaScopeTerminating),
|
||||
string(api.ResourceQuotaScopeNotTerminating),
|
||||
string(api.ResourceQuotaScopeBestEffort),
|
||||
string(api.ResourceQuotaScopeNotBestEffort),
|
||||
)
|
||||
|
||||
// IsStandardResourceQuotaScope returns true if the scope is a standard value
|
||||
func IsStandardResourceQuotaScope(str string) bool {
|
||||
return standardResourceQuotaScopes.Has(str)
|
||||
}
|
||||
|
||||
var podObjectCountQuotaResources = sets.NewString(
|
||||
string(api.ResourcePods),
|
||||
)
|
||||
|
||||
var podComputeQuotaResources = sets.NewString(
|
||||
string(api.ResourceCPU),
|
||||
string(api.ResourceMemory),
|
||||
string(api.ResourceLimitsCPU),
|
||||
string(api.ResourceLimitsMemory),
|
||||
string(api.ResourceRequestsCPU),
|
||||
string(api.ResourceRequestsMemory),
|
||||
)
|
||||
|
||||
// IsResourceQuotaScopeValidForResource returns true if the resource applies to the specified scope
|
||||
func IsResourceQuotaScopeValidForResource(scope api.ResourceQuotaScope, resource string) bool {
|
||||
switch scope {
|
||||
case api.ResourceQuotaScopeTerminating, api.ResourceQuotaScopeNotTerminating, api.ResourceQuotaScopeNotBestEffort:
|
||||
return podObjectCountQuotaResources.Has(resource) || podComputeQuotaResources.Has(resource)
|
||||
case api.ResourceQuotaScopeBestEffort:
|
||||
return podObjectCountQuotaResources.Has(resource)
|
||||
default:
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
var standardContainerResources = sets.NewString(
|
||||
string(api.ResourceCPU),
|
||||
string(api.ResourceMemory),
|
||||
string(api.ResourceEphemeralStorage),
|
||||
)
|
||||
|
||||
// IsStandardContainerResourceName returns true if the container can make a resource request
|
||||
// for the specified resource
|
||||
func IsStandardContainerResourceName(str string) bool {
|
||||
return standardContainerResources.Has(str) || IsHugePageResourceName(api.ResourceName(str))
|
||||
}
|
||||
|
||||
// IsExtendedResourceName returns true if the resource name is not in the
|
||||
// default namespace, or it has the opaque integer resource prefix.
|
||||
func IsExtendedResourceName(name api.ResourceName) bool {
|
||||
// TODO: Remove OIR part following deprecation.
|
||||
return !IsDefaultNamespaceResource(name) || IsOpaqueIntResourceName(name)
|
||||
}
|
||||
|
||||
// IsDefaultNamespaceResource returns true if the resource name is in the
|
||||
// *kubernetes.io/ namespace. Partially-qualified (unprefixed) names are
|
||||
// implicitly in the kubernetes.io/ namespace.
|
||||
func IsDefaultNamespaceResource(name api.ResourceName) bool {
|
||||
return !strings.Contains(string(name), "/") ||
|
||||
strings.Contains(string(name), api.ResourceDefaultNamespacePrefix)
|
||||
}
|
||||
|
||||
// IsOpaqueIntResourceName returns true if the resource name has the opaque
|
||||
// integer resource prefix.
|
||||
func IsOpaqueIntResourceName(name api.ResourceName) bool {
|
||||
return strings.HasPrefix(string(name), api.ResourceOpaqueIntPrefix)
|
||||
}
|
||||
|
||||
// OpaqueIntResourceName returns a ResourceName with the canonical opaque
|
||||
// integer prefix prepended. If the argument already has the prefix, it is
|
||||
// returned unmodified.
|
||||
func OpaqueIntResourceName(name string) api.ResourceName {
|
||||
if IsOpaqueIntResourceName(api.ResourceName(name)) {
|
||||
return api.ResourceName(name)
|
||||
}
|
||||
return api.ResourceName(fmt.Sprintf("%s%s", api.ResourceOpaqueIntPrefix, name))
|
||||
}
|
||||
|
||||
var overcommitBlacklist = sets.NewString(string(api.ResourceNvidiaGPU))
|
||||
|
||||
// IsOvercommitAllowed returns true if the resource is in the default
|
||||
// namespace and not blacklisted.
|
||||
func IsOvercommitAllowed(name api.ResourceName) bool {
|
||||
return IsDefaultNamespaceResource(name) &&
|
||||
!IsHugePageResourceName(name) &&
|
||||
!overcommitBlacklist.Has(string(name))
|
||||
}
|
||||
|
||||
var standardLimitRangeTypes = sets.NewString(
|
||||
string(api.LimitTypePod),
|
||||
string(api.LimitTypeContainer),
|
||||
string(api.LimitTypePersistentVolumeClaim),
|
||||
)
|
||||
|
||||
// IsStandardLimitRangeType returns true if the type is Pod or Container
|
||||
func IsStandardLimitRangeType(str string) bool {
|
||||
return standardLimitRangeTypes.Has(str)
|
||||
}
|
||||
|
||||
var standardQuotaResources = sets.NewString(
|
||||
string(api.ResourceCPU),
|
||||
string(api.ResourceMemory),
|
||||
string(api.ResourceEphemeralStorage),
|
||||
string(api.ResourceRequestsCPU),
|
||||
string(api.ResourceRequestsMemory),
|
||||
string(api.ResourceRequestsStorage),
|
||||
string(api.ResourceRequestsEphemeralStorage),
|
||||
string(api.ResourceLimitsCPU),
|
||||
string(api.ResourceLimitsMemory),
|
||||
string(api.ResourceLimitsEphemeralStorage),
|
||||
string(api.ResourcePods),
|
||||
string(api.ResourceQuotas),
|
||||
string(api.ResourceServices),
|
||||
string(api.ResourceReplicationControllers),
|
||||
string(api.ResourceSecrets),
|
||||
string(api.ResourcePersistentVolumeClaims),
|
||||
string(api.ResourceConfigMaps),
|
||||
string(api.ResourceServicesNodePorts),
|
||||
string(api.ResourceServicesLoadBalancers),
|
||||
)
|
||||
|
||||
// IsStandardQuotaResourceName returns true if the resource is known to
|
||||
// the quota tracking system
|
||||
func IsStandardQuotaResourceName(str string) bool {
|
||||
return standardQuotaResources.Has(str)
|
||||
}
|
||||
|
||||
var standardResources = sets.NewString(
|
||||
string(api.ResourceCPU),
|
||||
string(api.ResourceMemory),
|
||||
string(api.ResourceEphemeralStorage),
|
||||
string(api.ResourceRequestsCPU),
|
||||
string(api.ResourceRequestsMemory),
|
||||
string(api.ResourceRequestsEphemeralStorage),
|
||||
string(api.ResourceLimitsCPU),
|
||||
string(api.ResourceLimitsMemory),
|
||||
string(api.ResourceLimitsEphemeralStorage),
|
||||
string(api.ResourcePods),
|
||||
string(api.ResourceQuotas),
|
||||
string(api.ResourceServices),
|
||||
string(api.ResourceReplicationControllers),
|
||||
string(api.ResourceSecrets),
|
||||
string(api.ResourceConfigMaps),
|
||||
string(api.ResourcePersistentVolumeClaims),
|
||||
string(api.ResourceStorage),
|
||||
string(api.ResourceRequestsStorage),
|
||||
string(api.ResourceServicesNodePorts),
|
||||
string(api.ResourceServicesLoadBalancers),
|
||||
)
|
||||
|
||||
// IsStandardResourceName returns true if the resource is known to the system
|
||||
func IsStandardResourceName(str string) bool {
|
||||
return standardResources.Has(str) || IsHugePageResourceName(api.ResourceName(str))
|
||||
}
|
||||
|
||||
var integerResources = sets.NewString(
|
||||
string(api.ResourcePods),
|
||||
string(api.ResourceQuotas),
|
||||
string(api.ResourceServices),
|
||||
string(api.ResourceReplicationControllers),
|
||||
string(api.ResourceSecrets),
|
||||
string(api.ResourceConfigMaps),
|
||||
string(api.ResourcePersistentVolumeClaims),
|
||||
string(api.ResourceServicesNodePorts),
|
||||
string(api.ResourceServicesLoadBalancers),
|
||||
)
|
||||
|
||||
// IsIntegerResourceName returns true if the resource is measured in integer values
|
||||
func IsIntegerResourceName(str string) bool {
|
||||
return integerResources.Has(str) || IsExtendedResourceName(api.ResourceName(str))
|
||||
}
|
||||
|
||||
// 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 {
|
||||
return service.Spec.ClusterIP != api.ClusterIPNone && service.Spec.ClusterIP != ""
|
||||
}
|
||||
|
||||
// this function aims to check if the service's cluster IP is requested or not
|
||||
func IsServiceIPRequested(service *api.Service) bool {
|
||||
// ExternalName services are CNAME aliases to external ones. Ignore the IP.
|
||||
if service.Spec.Type == api.ServiceTypeExternalName {
|
||||
return false
|
||||
}
|
||||
return service.Spec.ClusterIP == ""
|
||||
}
|
||||
|
||||
var standardFinalizers = sets.NewString(
|
||||
string(api.FinalizerKubernetes),
|
||||
metav1.FinalizerOrphanDependents,
|
||||
metav1.FinalizerDeleteDependents,
|
||||
)
|
||||
|
||||
// HasAnnotation returns a bool if passed in annotation exists
|
||||
func HasAnnotation(obj api.ObjectMeta, ann string) bool {
|
||||
_, found := obj.Annotations[ann]
|
||||
return found
|
||||
}
|
||||
|
||||
// SetMetaDataAnnotation sets the annotation and value
|
||||
func SetMetaDataAnnotation(obj *api.ObjectMeta, ann string, value string) {
|
||||
if obj.Annotations == nil {
|
||||
obj.Annotations = make(map[string]string)
|
||||
}
|
||||
obj.Annotations[ann] = value
|
||||
}
|
||||
|
||||
func IsStandardFinalizerName(str string) bool {
|
||||
return standardFinalizers.Has(str)
|
||||
}
|
||||
|
||||
// AddToNodeAddresses appends the NodeAddresses to the passed-by-pointer slice,
|
||||
// only if they do not already exist
|
||||
func AddToNodeAddresses(addresses *[]api.NodeAddress, addAddresses ...api.NodeAddress) {
|
||||
for _, add := range addAddresses {
|
||||
exists := false
|
||||
for _, existing := range *addresses {
|
||||
if existing.Address == add.Address && existing.Type == add.Type {
|
||||
exists = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !exists {
|
||||
*addresses = append(*addresses, add)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: make method on LoadBalancerStatus?
|
||||
func LoadBalancerStatusEqual(l, r *api.LoadBalancerStatus) bool {
|
||||
return ingressSliceEqual(l.Ingress, r.Ingress)
|
||||
}
|
||||
|
||||
func ingressSliceEqual(lhs, rhs []api.LoadBalancerIngress) bool {
|
||||
if len(lhs) != len(rhs) {
|
||||
return false
|
||||
}
|
||||
for i := range lhs {
|
||||
if !ingressEqual(&lhs[i], &rhs[i]) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func ingressEqual(lhs, rhs *api.LoadBalancerIngress) bool {
|
||||
if lhs.IP != rhs.IP {
|
||||
return false
|
||||
}
|
||||
if lhs.Hostname != rhs.Hostname {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// TODO: make method on LoadBalancerStatus?
|
||||
func LoadBalancerStatusDeepCopy(lb *api.LoadBalancerStatus) *api.LoadBalancerStatus {
|
||||
c := &api.LoadBalancerStatus{}
|
||||
c.Ingress = make([]api.LoadBalancerIngress, len(lb.Ingress))
|
||||
for i := range lb.Ingress {
|
||||
c.Ingress[i] = lb.Ingress[i]
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
// GetAccessModesAsString returns a string representation of an array of access modes.
|
||||
// modes, when present, are always in the same order: RWO,ROX,RWX.
|
||||
func GetAccessModesAsString(modes []api.PersistentVolumeAccessMode) string {
|
||||
modes = removeDuplicateAccessModes(modes)
|
||||
modesStr := []string{}
|
||||
if containsAccessMode(modes, api.ReadWriteOnce) {
|
||||
modesStr = append(modesStr, "RWO")
|
||||
}
|
||||
if containsAccessMode(modes, api.ReadOnlyMany) {
|
||||
modesStr = append(modesStr, "ROX")
|
||||
}
|
||||
if containsAccessMode(modes, api.ReadWriteMany) {
|
||||
modesStr = append(modesStr, "RWX")
|
||||
}
|
||||
return strings.Join(modesStr, ",")
|
||||
}
|
||||
|
||||
// GetAccessModesAsString returns an array of AccessModes from a string created by GetAccessModesAsString
|
||||
func GetAccessModesFromString(modes string) []api.PersistentVolumeAccessMode {
|
||||
strmodes := strings.Split(modes, ",")
|
||||
accessModes := []api.PersistentVolumeAccessMode{}
|
||||
for _, s := range strmodes {
|
||||
s = strings.Trim(s, " ")
|
||||
switch {
|
||||
case s == "RWO":
|
||||
accessModes = append(accessModes, api.ReadWriteOnce)
|
||||
case s == "ROX":
|
||||
accessModes = append(accessModes, api.ReadOnlyMany)
|
||||
case s == "RWX":
|
||||
accessModes = append(accessModes, api.ReadWriteMany)
|
||||
}
|
||||
}
|
||||
return accessModes
|
||||
}
|
||||
|
||||
// removeDuplicateAccessModes returns an array of access modes without any duplicates
|
||||
func removeDuplicateAccessModes(modes []api.PersistentVolumeAccessMode) []api.PersistentVolumeAccessMode {
|
||||
accessModes := []api.PersistentVolumeAccessMode{}
|
||||
for _, m := range modes {
|
||||
if !containsAccessMode(accessModes, m) {
|
||||
accessModes = append(accessModes, m)
|
||||
}
|
||||
}
|
||||
return accessModes
|
||||
}
|
||||
|
||||
func containsAccessMode(modes []api.PersistentVolumeAccessMode, mode api.PersistentVolumeAccessMode) bool {
|
||||
for _, m := range modes {
|
||||
if m == mode {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// NodeSelectorRequirementsAsSelector converts the []NodeSelectorRequirement api type into a struct that implements
|
||||
// labels.Selector.
|
||||
func NodeSelectorRequirementsAsSelector(nsm []api.NodeSelectorRequirement) (labels.Selector, error) {
|
||||
if len(nsm) == 0 {
|
||||
return labels.Nothing(), nil
|
||||
}
|
||||
selector := labels.NewSelector()
|
||||
for _, expr := range nsm {
|
||||
var op selection.Operator
|
||||
switch expr.Operator {
|
||||
case api.NodeSelectorOpIn:
|
||||
op = selection.In
|
||||
case api.NodeSelectorOpNotIn:
|
||||
op = selection.NotIn
|
||||
case api.NodeSelectorOpExists:
|
||||
op = selection.Exists
|
||||
case api.NodeSelectorOpDoesNotExist:
|
||||
op = selection.DoesNotExist
|
||||
case api.NodeSelectorOpGt:
|
||||
op = selection.GreaterThan
|
||||
case api.NodeSelectorOpLt:
|
||||
op = selection.LessThan
|
||||
default:
|
||||
return nil, fmt.Errorf("%q is not a valid node selector operator", expr.Operator)
|
||||
}
|
||||
r, err := labels.NewRequirement(expr.Key, op, expr.Values)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
selector = selector.Add(*r)
|
||||
}
|
||||
return selector, nil
|
||||
}
|
||||
|
||||
// GetTolerationsFromPodAnnotations gets the json serialized tolerations data from Pod.Annotations
|
||||
// and converts it to the []Toleration type in api.
|
||||
func GetTolerationsFromPodAnnotations(annotations map[string]string) ([]api.Toleration, error) {
|
||||
var tolerations []api.Toleration
|
||||
if len(annotations) > 0 && annotations[api.TolerationsAnnotationKey] != "" {
|
||||
err := json.Unmarshal([]byte(annotations[api.TolerationsAnnotationKey]), &tolerations)
|
||||
if err != nil {
|
||||
return tolerations, err
|
||||
}
|
||||
}
|
||||
return tolerations, nil
|
||||
}
|
||||
|
||||
// AddOrUpdateTolerationInPod tries to add a toleration to the pod's toleration list.
|
||||
// Returns true if something was updated, false otherwise.
|
||||
func AddOrUpdateTolerationInPod(pod *api.Pod, toleration *api.Toleration) bool {
|
||||
podTolerations := pod.Spec.Tolerations
|
||||
|
||||
var newTolerations []api.Toleration
|
||||
updated := false
|
||||
for i := range podTolerations {
|
||||
if toleration.MatchToleration(&podTolerations[i]) {
|
||||
if Semantic.DeepEqual(toleration, podTolerations[i]) {
|
||||
return false
|
||||
}
|
||||
newTolerations = append(newTolerations, *toleration)
|
||||
updated = true
|
||||
continue
|
||||
}
|
||||
|
||||
newTolerations = append(newTolerations, podTolerations[i])
|
||||
}
|
||||
|
||||
if !updated {
|
||||
newTolerations = append(newTolerations, *toleration)
|
||||
}
|
||||
|
||||
pod.Spec.Tolerations = newTolerations
|
||||
return true
|
||||
}
|
||||
|
||||
// TolerationToleratesTaint checks if the toleration tolerates the taint.
|
||||
func TolerationToleratesTaint(toleration *api.Toleration, taint *api.Taint) bool {
|
||||
if len(toleration.Effect) != 0 && toleration.Effect != taint.Effect {
|
||||
return false
|
||||
}
|
||||
|
||||
if toleration.Key != taint.Key {
|
||||
return false
|
||||
}
|
||||
// TODO: Use proper defaulting when Toleration becomes a field of PodSpec
|
||||
if (len(toleration.Operator) == 0 || toleration.Operator == api.TolerationOpEqual) && toleration.Value == taint.Value {
|
||||
return true
|
||||
}
|
||||
if toleration.Operator == api.TolerationOpExists {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// TaintToleratedByTolerations checks if taint is tolerated by any of the tolerations.
|
||||
func TaintToleratedByTolerations(taint *api.Taint, tolerations []api.Toleration) bool {
|
||||
tolerated := false
|
||||
for i := range tolerations {
|
||||
if TolerationToleratesTaint(&tolerations[i], taint) {
|
||||
tolerated = true
|
||||
break
|
||||
}
|
||||
}
|
||||
return tolerated
|
||||
}
|
||||
|
||||
// GetTaintsFromNodeAnnotations gets the json serialized taints data from Pod.Annotations
|
||||
// and converts it to the []Taint type in api.
|
||||
func GetTaintsFromNodeAnnotations(annotations map[string]string) ([]api.Taint, error) {
|
||||
var taints []api.Taint
|
||||
if len(annotations) > 0 && annotations[api.TaintsAnnotationKey] != "" {
|
||||
err := json.Unmarshal([]byte(annotations[api.TaintsAnnotationKey]), &taints)
|
||||
if err != nil {
|
||||
return []api.Taint{}, err
|
||||
}
|
||||
}
|
||||
return taints, nil
|
||||
}
|
||||
|
||||
// SysctlsFromPodAnnotations parses the sysctl annotations into a slice of safe Sysctls
|
||||
// and a slice of unsafe Sysctls. This is only a convenience wrapper around
|
||||
// SysctlsFromPodAnnotation.
|
||||
func SysctlsFromPodAnnotations(a map[string]string) ([]api.Sysctl, []api.Sysctl, error) {
|
||||
safe, err := SysctlsFromPodAnnotation(a[api.SysctlsPodAnnotationKey])
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
unsafe, err := SysctlsFromPodAnnotation(a[api.UnsafeSysctlsPodAnnotationKey])
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
return safe, unsafe, nil
|
||||
}
|
||||
|
||||
// SysctlsFromPodAnnotation parses an annotation value into a slice of Sysctls.
|
||||
func SysctlsFromPodAnnotation(annotation string) ([]api.Sysctl, error) {
|
||||
if len(annotation) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
kvs := strings.Split(annotation, ",")
|
||||
sysctls := make([]api.Sysctl, len(kvs))
|
||||
for i, kv := range kvs {
|
||||
cs := strings.Split(kv, "=")
|
||||
if len(cs) != 2 || len(cs[0]) == 0 {
|
||||
return nil, fmt.Errorf("sysctl %q not of the format sysctl_name=value", kv)
|
||||
}
|
||||
sysctls[i].Name = cs[0]
|
||||
sysctls[i].Value = cs[1]
|
||||
}
|
||||
return sysctls, nil
|
||||
}
|
||||
|
||||
// PodAnnotationsFromSysctls creates an annotation value for a slice of Sysctls.
|
||||
func PodAnnotationsFromSysctls(sysctls []api.Sysctl) string {
|
||||
if len(sysctls) == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
kvs := make([]string, len(sysctls))
|
||||
for i := range sysctls {
|
||||
kvs[i] = fmt.Sprintf("%s=%s", sysctls[i].Name, sysctls[i].Value)
|
||||
}
|
||||
return strings.Join(kvs, ",")
|
||||
}
|
||||
|
||||
// GetPersistentVolumeClass returns StorageClassName.
|
||||
func GetPersistentVolumeClass(volume *api.PersistentVolume) string {
|
||||
// Use beta annotation first
|
||||
if class, found := volume.Annotations[api.BetaStorageClassAnnotation]; found {
|
||||
return class
|
||||
}
|
||||
|
||||
return volume.Spec.StorageClassName
|
||||
}
|
||||
|
||||
// GetPersistentVolumeClaimClass returns StorageClassName. If no storage class was
|
||||
// requested, it returns "".
|
||||
func GetPersistentVolumeClaimClass(claim *api.PersistentVolumeClaim) string {
|
||||
// Use beta annotation first
|
||||
if class, found := claim.Annotations[api.BetaStorageClassAnnotation]; found {
|
||||
return class
|
||||
}
|
||||
|
||||
if claim.Spec.StorageClassName != nil {
|
||||
return *claim.Spec.StorageClassName
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
// PersistentVolumeClaimHasClass returns true if given claim has set StorageClassName field.
|
||||
func PersistentVolumeClaimHasClass(claim *api.PersistentVolumeClaim) bool {
|
||||
// Use beta annotation first
|
||||
if _, found := claim.Annotations[api.BetaStorageClassAnnotation]; found {
|
||||
return true
|
||||
}
|
||||
|
||||
if claim.Spec.StorageClassName != nil {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// GetStorageNodeAffinityFromAnnotation gets the json serialized data from PersistentVolume.Annotations
|
||||
// and converts it to the NodeAffinity type in api.
|
||||
// TODO: update when storage node affinity graduates to beta
|
||||
func GetStorageNodeAffinityFromAnnotation(annotations map[string]string) (*api.NodeAffinity, error) {
|
||||
if len(annotations) > 0 && annotations[api.AlphaStorageNodeAffinityAnnotation] != "" {
|
||||
var affinity api.NodeAffinity
|
||||
err := json.Unmarshal([]byte(annotations[api.AlphaStorageNodeAffinityAnnotation]), &affinity)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &affinity, nil
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// Converts NodeAffinity type to Alpha annotation for use in PersistentVolumes
|
||||
// TODO: update when storage node affinity graduates to beta
|
||||
func StorageNodeAffinityToAlphaAnnotation(annotations map[string]string, affinity *api.NodeAffinity) error {
|
||||
if affinity == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
json, err := json.Marshal(*affinity)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
annotations[api.AlphaStorageNodeAffinityAnnotation] = string(json)
|
||||
return nil
|
||||
}
|
||||
490
vendor/k8s.io/kubernetes/pkg/api/helper/helpers_test.go
generated
vendored
490
vendor/k8s.io/kubernetes/pkg/api/helper/helpers_test.go
generated
vendored
|
|
@ -1,490 +0,0 @@
|
|||
/*
|
||||
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 helper
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
)
|
||||
|
||||
func TestSemantic(t *testing.T) {
|
||||
table := []struct {
|
||||
a, b interface{}
|
||||
shouldEqual bool
|
||||
}{
|
||||
{resource.MustParse("0"), resource.Quantity{}, true},
|
||||
{resource.Quantity{}, resource.MustParse("0"), true},
|
||||
{resource.Quantity{}, resource.MustParse("1m"), false},
|
||||
{
|
||||
resource.NewQuantity(5, resource.BinarySI),
|
||||
resource.NewQuantity(5, resource.DecimalSI),
|
||||
true,
|
||||
},
|
||||
{resource.MustParse("2m"), resource.MustParse("1m"), false},
|
||||
}
|
||||
|
||||
for index, item := range table {
|
||||
if e, a := item.shouldEqual, Semantic.DeepEqual(item.a, item.b); e != a {
|
||||
t.Errorf("case[%d], expected %v, got %v.", index, e, a)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsStandardResource(t *testing.T) {
|
||||
testCases := []struct {
|
||||
input string
|
||||
output bool
|
||||
}{
|
||||
{"cpu", true},
|
||||
{"memory", true},
|
||||
{"disk", false},
|
||||
{"blah", false},
|
||||
{"x.y.z", false},
|
||||
{"hugepages-2Mi", true},
|
||||
}
|
||||
for i, tc := range testCases {
|
||||
if IsStandardResourceName(tc.input) != tc.output {
|
||||
t.Errorf("case[%d], input: %s, expected: %t, got: %t", i, tc.input, tc.output, !tc.output)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsStandardContainerResource(t *testing.T) {
|
||||
testCases := []struct {
|
||||
input string
|
||||
output bool
|
||||
}{
|
||||
{"cpu", true},
|
||||
{"memory", true},
|
||||
{"disk", false},
|
||||
{"hugepages-2Mi", true},
|
||||
}
|
||||
for i, tc := range testCases {
|
||||
if IsStandardContainerResourceName(tc.input) != tc.output {
|
||||
t.Errorf("case[%d], input: %s, expected: %t, got: %t", i, tc.input, tc.output, !tc.output)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestAddToNodeAddresses(t *testing.T) {
|
||||
testCases := []struct {
|
||||
existing []api.NodeAddress
|
||||
toAdd []api.NodeAddress
|
||||
expected []api.NodeAddress
|
||||
}{
|
||||
{
|
||||
existing: []api.NodeAddress{},
|
||||
toAdd: []api.NodeAddress{},
|
||||
expected: []api.NodeAddress{},
|
||||
},
|
||||
{
|
||||
existing: []api.NodeAddress{},
|
||||
toAdd: []api.NodeAddress{
|
||||
{Type: api.NodeExternalIP, Address: "1.1.1.1"},
|
||||
{Type: api.NodeHostName, Address: "localhost"},
|
||||
},
|
||||
expected: []api.NodeAddress{
|
||||
{Type: api.NodeExternalIP, Address: "1.1.1.1"},
|
||||
{Type: api.NodeHostName, Address: "localhost"},
|
||||
},
|
||||
},
|
||||
{
|
||||
existing: []api.NodeAddress{},
|
||||
toAdd: []api.NodeAddress{
|
||||
{Type: api.NodeExternalIP, Address: "1.1.1.1"},
|
||||
{Type: api.NodeExternalIP, Address: "1.1.1.1"},
|
||||
},
|
||||
expected: []api.NodeAddress{
|
||||
{Type: api.NodeExternalIP, Address: "1.1.1.1"},
|
||||
},
|
||||
},
|
||||
{
|
||||
existing: []api.NodeAddress{
|
||||
{Type: api.NodeExternalIP, Address: "1.1.1.1"},
|
||||
{Type: api.NodeInternalIP, Address: "10.1.1.1"},
|
||||
},
|
||||
toAdd: []api.NodeAddress{
|
||||
{Type: api.NodeExternalIP, Address: "1.1.1.1"},
|
||||
{Type: api.NodeHostName, Address: "localhost"},
|
||||
},
|
||||
expected: []api.NodeAddress{
|
||||
{Type: api.NodeExternalIP, Address: "1.1.1.1"},
|
||||
{Type: api.NodeInternalIP, Address: "10.1.1.1"},
|
||||
{Type: api.NodeHostName, Address: "localhost"},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for i, tc := range testCases {
|
||||
AddToNodeAddresses(&tc.existing, tc.toAdd...)
|
||||
if !Semantic.DeepEqual(tc.expected, tc.existing) {
|
||||
t.Errorf("case[%d], expected: %v, got: %v", i, tc.expected, tc.existing)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetAccessModesFromString(t *testing.T) {
|
||||
modes := GetAccessModesFromString("ROX")
|
||||
if !containsAccessMode(modes, api.ReadOnlyMany) {
|
||||
t.Errorf("Expected mode %s, but got %+v", api.ReadOnlyMany, modes)
|
||||
}
|
||||
|
||||
modes = GetAccessModesFromString("ROX,RWX")
|
||||
if !containsAccessMode(modes, api.ReadOnlyMany) {
|
||||
t.Errorf("Expected mode %s, but got %+v", api.ReadOnlyMany, modes)
|
||||
}
|
||||
if !containsAccessMode(modes, api.ReadWriteMany) {
|
||||
t.Errorf("Expected mode %s, but got %+v", api.ReadWriteMany, modes)
|
||||
}
|
||||
|
||||
modes = GetAccessModesFromString("RWO,ROX,RWX")
|
||||
if !containsAccessMode(modes, api.ReadOnlyMany) {
|
||||
t.Errorf("Expected mode %s, but got %+v", api.ReadOnlyMany, modes)
|
||||
}
|
||||
if !containsAccessMode(modes, api.ReadWriteMany) {
|
||||
t.Errorf("Expected mode %s, but got %+v", api.ReadWriteMany, modes)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRemoveDuplicateAccessModes(t *testing.T) {
|
||||
modes := []api.PersistentVolumeAccessMode{
|
||||
api.ReadWriteOnce, api.ReadOnlyMany, api.ReadOnlyMany, api.ReadOnlyMany,
|
||||
}
|
||||
modes = removeDuplicateAccessModes(modes)
|
||||
if len(modes) != 2 {
|
||||
t.Errorf("Expected 2 distinct modes in set but found %v", len(modes))
|
||||
}
|
||||
}
|
||||
|
||||
func TestNodeSelectorRequirementsAsSelector(t *testing.T) {
|
||||
matchExpressions := []api.NodeSelectorRequirement{{
|
||||
Key: "foo",
|
||||
Operator: api.NodeSelectorOpIn,
|
||||
Values: []string{"bar", "baz"},
|
||||
}}
|
||||
mustParse := func(s string) labels.Selector {
|
||||
out, e := labels.Parse(s)
|
||||
if e != nil {
|
||||
panic(e)
|
||||
}
|
||||
return out
|
||||
}
|
||||
tc := []struct {
|
||||
in []api.NodeSelectorRequirement
|
||||
out labels.Selector
|
||||
expectErr bool
|
||||
}{
|
||||
{in: nil, out: labels.Nothing()},
|
||||
{in: []api.NodeSelectorRequirement{}, out: labels.Nothing()},
|
||||
{
|
||||
in: matchExpressions,
|
||||
out: mustParse("foo in (baz,bar)"),
|
||||
},
|
||||
{
|
||||
in: []api.NodeSelectorRequirement{{
|
||||
Key: "foo",
|
||||
Operator: api.NodeSelectorOpExists,
|
||||
Values: []string{"bar", "baz"},
|
||||
}},
|
||||
expectErr: true,
|
||||
},
|
||||
{
|
||||
in: []api.NodeSelectorRequirement{{
|
||||
Key: "foo",
|
||||
Operator: api.NodeSelectorOpGt,
|
||||
Values: []string{"1"},
|
||||
}},
|
||||
out: mustParse("foo>1"),
|
||||
},
|
||||
{
|
||||
in: []api.NodeSelectorRequirement{{
|
||||
Key: "bar",
|
||||
Operator: api.NodeSelectorOpLt,
|
||||
Values: []string{"7"},
|
||||
}},
|
||||
out: mustParse("bar<7"),
|
||||
},
|
||||
}
|
||||
|
||||
for i, tc := range tc {
|
||||
out, err := NodeSelectorRequirementsAsSelector(tc.in)
|
||||
if err == nil && tc.expectErr {
|
||||
t.Errorf("[%v]expected error but got none.", i)
|
||||
}
|
||||
if err != nil && !tc.expectErr {
|
||||
t.Errorf("[%v]did not expect error but got: %v", i, err)
|
||||
}
|
||||
if !reflect.DeepEqual(out, tc.out) {
|
||||
t.Errorf("[%v]expected:\n\t%+v\nbut got:\n\t%+v", i, tc.out, out)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSysctlsFromPodAnnotation(t *testing.T) {
|
||||
type Test struct {
|
||||
annotation string
|
||||
expectValue []api.Sysctl
|
||||
expectErr bool
|
||||
}
|
||||
for i, test := range []Test{
|
||||
{
|
||||
annotation: "",
|
||||
expectValue: nil,
|
||||
},
|
||||
{
|
||||
annotation: "foo.bar",
|
||||
expectErr: true,
|
||||
},
|
||||
{
|
||||
annotation: "=123",
|
||||
expectErr: true,
|
||||
},
|
||||
{
|
||||
annotation: "foo.bar=",
|
||||
expectValue: []api.Sysctl{{Name: "foo.bar", Value: ""}},
|
||||
},
|
||||
{
|
||||
annotation: "foo.bar=42",
|
||||
expectValue: []api.Sysctl{{Name: "foo.bar", Value: "42"}},
|
||||
},
|
||||
{
|
||||
annotation: "foo.bar=42,",
|
||||
expectErr: true,
|
||||
},
|
||||
{
|
||||
annotation: "foo.bar=42,abc.def=1",
|
||||
expectValue: []api.Sysctl{{Name: "foo.bar", Value: "42"}, {Name: "abc.def", Value: "1"}},
|
||||
},
|
||||
} {
|
||||
sysctls, err := SysctlsFromPodAnnotation(test.annotation)
|
||||
if test.expectErr && err == nil {
|
||||
t.Errorf("[%v]expected error but got none", i)
|
||||
} else if !test.expectErr && err != nil {
|
||||
t.Errorf("[%v]did not expect error but got: %v", i, err)
|
||||
} else if !reflect.DeepEqual(sysctls, test.expectValue) {
|
||||
t.Errorf("[%v]expect value %v but got %v", i, test.expectValue, sysctls)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: remove when alpha support for topology constraints is removed
|
||||
func TestGetNodeAffinityFromAnnotations(t *testing.T) {
|
||||
testCases := []struct {
|
||||
annotations map[string]string
|
||||
expectErr bool
|
||||
}{
|
||||
{
|
||||
annotations: nil,
|
||||
expectErr: false,
|
||||
},
|
||||
{
|
||||
annotations: map[string]string{},
|
||||
expectErr: false,
|
||||
},
|
||||
{
|
||||
annotations: map[string]string{
|
||||
api.AlphaStorageNodeAffinityAnnotation: `{
|
||||
"requiredDuringSchedulingIgnoredDuringExecution": {
|
||||
"nodeSelectorTerms": [
|
||||
{ "matchExpressions": [
|
||||
{ "key": "test-key1",
|
||||
"operator": "In",
|
||||
"values": ["test-value1", "test-value2"]
|
||||
},
|
||||
{ "key": "test-key2",
|
||||
"operator": "In",
|
||||
"values": ["test-value1", "test-value2"]
|
||||
}
|
||||
]}
|
||||
]}
|
||||
}`,
|
||||
},
|
||||
expectErr: false,
|
||||
},
|
||||
{
|
||||
annotations: map[string]string{
|
||||
api.AlphaStorageNodeAffinityAnnotation: `[{
|
||||
"requiredDuringSchedulingIgnoredDuringExecution": {
|
||||
"nodeSelectorTerms": [
|
||||
{ "matchExpressions": [
|
||||
{ "key": "test-key1",
|
||||
"operator": "In",
|
||||
"values": ["test-value1", "test-value2"]
|
||||
},
|
||||
{ "key": "test-key2",
|
||||
"operator": "In",
|
||||
"values": ["test-value1", "test-value2"]
|
||||
}
|
||||
]}
|
||||
]}
|
||||
}]`,
|
||||
},
|
||||
expectErr: true,
|
||||
},
|
||||
{
|
||||
annotations: map[string]string{
|
||||
api.AlphaStorageNodeAffinityAnnotation: `{
|
||||
"requiredDuringSchedulingIgnoredDuringExecution": {
|
||||
"nodeSelectorTerms":
|
||||
"matchExpressions": [
|
||||
{ "key": "test-key1",
|
||||
"operator": "In",
|
||||
"values": ["test-value1", "test-value2"]
|
||||
},
|
||||
{ "key": "test-key2",
|
||||
"operator": "In",
|
||||
"values": ["test-value1", "test-value2"]
|
||||
}
|
||||
]}
|
||||
}
|
||||
}`,
|
||||
},
|
||||
expectErr: true,
|
||||
},
|
||||
}
|
||||
|
||||
for i, tc := range testCases {
|
||||
_, err := GetStorageNodeAffinityFromAnnotation(tc.annotations)
|
||||
if err == nil && tc.expectErr {
|
||||
t.Errorf("[%v]expected error but got none.", i)
|
||||
}
|
||||
if err != nil && !tc.expectErr {
|
||||
t.Errorf("[%v]did not expect error but got: %v", i, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsHugePageResourceName(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name api.ResourceName
|
||||
result bool
|
||||
}{
|
||||
{
|
||||
name: api.ResourceName("hugepages-2Mi"),
|
||||
result: true,
|
||||
},
|
||||
{
|
||||
name: api.ResourceName("hugepages-1Gi"),
|
||||
result: true,
|
||||
},
|
||||
{
|
||||
name: api.ResourceName("cpu"),
|
||||
result: false,
|
||||
},
|
||||
{
|
||||
name: api.ResourceName("memory"),
|
||||
result: false,
|
||||
},
|
||||
}
|
||||
for _, testCase := range testCases {
|
||||
if testCase.result != IsHugePageResourceName(testCase.name) {
|
||||
t.Errorf("resource: %v expected result: %v", testCase.name, testCase.result)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestHugePageResourceName(t *testing.T) {
|
||||
testCases := []struct {
|
||||
pageSize resource.Quantity
|
||||
name api.ResourceName
|
||||
}{
|
||||
{
|
||||
pageSize: resource.MustParse("2Mi"),
|
||||
name: api.ResourceName("hugepages-2Mi"),
|
||||
},
|
||||
{
|
||||
pageSize: resource.MustParse("1Gi"),
|
||||
name: api.ResourceName("hugepages-1Gi"),
|
||||
},
|
||||
{
|
||||
// verify we do not regress our canonical representation
|
||||
pageSize: *resource.NewQuantity(int64(2097152), resource.BinarySI),
|
||||
name: api.ResourceName("hugepages-2Mi"),
|
||||
},
|
||||
}
|
||||
for _, testCase := range testCases {
|
||||
if result := HugePageResourceName(testCase.pageSize); result != testCase.name {
|
||||
t.Errorf("pageSize: %v, expected: %v, but got: %v", testCase.pageSize.String(), testCase.name, result.String())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestHugePageSizeFromResourceName(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name api.ResourceName
|
||||
expectErr bool
|
||||
pageSize resource.Quantity
|
||||
}{
|
||||
{
|
||||
name: api.ResourceName("hugepages-2Mi"),
|
||||
pageSize: resource.MustParse("2Mi"),
|
||||
expectErr: false,
|
||||
},
|
||||
{
|
||||
name: api.ResourceName("hugepages-1Gi"),
|
||||
pageSize: resource.MustParse("1Gi"),
|
||||
expectErr: false,
|
||||
},
|
||||
{
|
||||
name: api.ResourceName("hugepages-bad"),
|
||||
expectErr: true,
|
||||
},
|
||||
}
|
||||
for _, testCase := range testCases {
|
||||
value, err := HugePageSizeFromResourceName(testCase.name)
|
||||
if testCase.expectErr && err == nil {
|
||||
t.Errorf("Expected an error for %v", testCase.name)
|
||||
} else if !testCase.expectErr && err != nil {
|
||||
t.Errorf("Unexpected error for %v, got %v", testCase.name, err)
|
||||
} else if testCase.pageSize.Value() != value.Value() {
|
||||
t.Errorf("Unexpected pageSize for resource %v got %v", testCase.name, value.String())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsOvercommitAllowed(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name api.ResourceName
|
||||
allowed bool
|
||||
}{
|
||||
{
|
||||
name: api.ResourceCPU,
|
||||
allowed: true,
|
||||
},
|
||||
{
|
||||
name: api.ResourceMemory,
|
||||
allowed: true,
|
||||
},
|
||||
{
|
||||
name: api.ResourceNvidiaGPU,
|
||||
allowed: false,
|
||||
},
|
||||
{
|
||||
name: HugePageResourceName(resource.MustParse("2Mi")),
|
||||
allowed: false,
|
||||
},
|
||||
}
|
||||
for _, testCase := range testCases {
|
||||
if testCase.allowed != IsOvercommitAllowed(testCase.name) {
|
||||
t.Errorf("Unexpected result for %v", testCase.name)
|
||||
}
|
||||
}
|
||||
}
|
||||
46
vendor/k8s.io/kubernetes/pkg/api/install/BUILD
generated
vendored
46
vendor/k8s.io/kubernetes/pkg/api/install/BUILD
generated
vendored
|
|
@ -1,46 +0,0 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
"go_test",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["install.go"],
|
||||
deps = [
|
||||
"//pkg/api:go_default_library",
|
||||
"//pkg/api/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apimachinery/announced:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apimachinery/registered:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["install_test.go"],
|
||||
library = ":go_default_library",
|
||||
deps = [
|
||||
"//pkg/api:go_default_library",
|
||||
"//vendor/k8s.io/api/core/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
10
vendor/k8s.io/kubernetes/pkg/api/install/OWNERS
generated
vendored
10
vendor/k8s.io/kubernetes/pkg/api/install/OWNERS
generated
vendored
|
|
@ -1,10 +0,0 @@
|
|||
reviewers:
|
||||
- lavalamp
|
||||
- smarterclayton
|
||||
- deads2k
|
||||
- caesarxuchao
|
||||
- liggitt
|
||||
- nikhiljindal
|
||||
- dims
|
||||
- david-mcmahon
|
||||
- feihujiang
|
||||
69
vendor/k8s.io/kubernetes/pkg/api/install/install.go
generated
vendored
69
vendor/k8s.io/kubernetes/pkg/api/install/install.go
generated
vendored
|
|
@ -1,69 +0,0 @@
|
|||
/*
|
||||
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 install installs the v1 monolithic api, making it available as an
|
||||
// option to all of the API encoding/decoding machinery.
|
||||
package install
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/apimachinery/announced"
|
||||
"k8s.io/apimachinery/pkg/apimachinery/registered"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/v1"
|
||||
)
|
||||
|
||||
func init() {
|
||||
Install(api.GroupFactoryRegistry, api.Registry, api.Scheme)
|
||||
}
|
||||
|
||||
// Install registers the API group and adds types to a scheme
|
||||
func Install(groupFactoryRegistry announced.APIGroupFactoryRegistry, registry *registered.APIRegistrationManager, scheme *runtime.Scheme) {
|
||||
if err := announced.NewGroupMetaFactory(
|
||||
&announced.GroupMetaFactoryArgs{
|
||||
GroupName: api.GroupName,
|
||||
VersionPreferenceOrder: []string{v1.SchemeGroupVersion.Version},
|
||||
AddInternalObjectsToScheme: api.AddToScheme,
|
||||
RootScopedKinds: sets.NewString(
|
||||
"Node",
|
||||
"Namespace",
|
||||
"PersistentVolume",
|
||||
"ComponentStatus",
|
||||
),
|
||||
IgnoredKinds: sets.NewString(
|
||||
"ListOptions",
|
||||
"DeleteOptions",
|
||||
"Status",
|
||||
"PodLogOptions",
|
||||
"PodExecOptions",
|
||||
"PodAttachOptions",
|
||||
"PodPortForwardOptions",
|
||||
"PodProxyOptions",
|
||||
"NodeProxyOptions",
|
||||
"ServiceProxyOptions",
|
||||
"ThirdPartyResource",
|
||||
"ThirdPartyResourceData",
|
||||
"ThirdPartyResourceList",
|
||||
),
|
||||
},
|
||||
announced.VersionToSchemeFunc{
|
||||
v1.SchemeGroupVersion.Version: v1.AddToScheme,
|
||||
},
|
||||
).Announce(groupFactoryRegistry).RegisterAndEnable(registry, scheme); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
139
vendor/k8s.io/kubernetes/pkg/api/install/install_test.go
generated
vendored
139
vendor/k8s.io/kubernetes/pkg/api/install/install_test.go
generated
vendored
|
|
@ -1,139 +0,0 @@
|
|||
/*
|
||||
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 install
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
internal "k8s.io/kubernetes/pkg/api"
|
||||
)
|
||||
|
||||
func TestResourceVersioner(t *testing.T) {
|
||||
g, err := internal.Registry.Group(v1.GroupName)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
intf, err := g.DefaultInterfacesFor(v1.SchemeGroupVersion)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
accessor := intf.MetadataAccessor
|
||||
|
||||
pod := internal.Pod{ObjectMeta: metav1.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: metav1.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 registered rather than testapi here, because we
|
||||
// want to test if the package install and package registered work as expected.
|
||||
data, err := runtime.Encode(internal.Codecs.LegacyCodec(internal.Registry.GroupOrDie(internal.GroupName).GroupVersion), &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 != internal.Registry.GroupOrDie(internal.GroupName).GroupVersion.Version || other.Kind != "Pod" {
|
||||
t.Errorf("unexpected unmarshalled object %#v", other)
|
||||
}
|
||||
}
|
||||
|
||||
func TestInterfacesFor(t *testing.T) {
|
||||
if _, err := internal.Registry.GroupOrDie(internal.GroupName).InterfacesFor(internal.SchemeGroupVersion); err == nil {
|
||||
t.Fatalf("unexpected non-error: %v", err)
|
||||
}
|
||||
for i, version := range internal.Registry.GroupOrDie(internal.GroupName).GroupVersions {
|
||||
if vi, err := internal.Registry.GroupOrDie(internal.GroupName).InterfacesFor(version); err != nil || vi == nil {
|
||||
t.Fatalf("%d: unexpected result: %v", i, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestRESTMapper(t *testing.T) {
|
||||
gv := schema.GroupVersion{Group: "", Version: "v1"}
|
||||
rcGVK := gv.WithKind("ReplicationController")
|
||||
podTemplateGVK := gv.WithKind("PodTemplate")
|
||||
|
||||
if gvk, err := internal.Registry.RESTMapper().KindFor(internal.SchemeGroupVersion.WithResource("replicationcontrollers")); err != nil || gvk != rcGVK {
|
||||
t.Errorf("unexpected version mapping: %v %v", gvk, err)
|
||||
}
|
||||
|
||||
if m, err := internal.Registry.GroupOrDie(internal.GroupName).RESTMapper.RESTMapping(podTemplateGVK.GroupKind(), ""); err != nil || m.GroupVersionKind != podTemplateGVK || m.Resource != "podtemplates" {
|
||||
t.Errorf("unexpected version mapping: %#v %v", m, err)
|
||||
}
|
||||
|
||||
for _, version := range internal.Registry.GroupOrDie(internal.GroupName).GroupVersions {
|
||||
mapping, err := internal.Registry.GroupOrDie(internal.GroupName).RESTMapper.RESTMapping(rcGVK.GroupKind(), version.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.GroupVersionKind.GroupVersion() != version {
|
||||
t.Errorf("incorrect version: %v", mapping)
|
||||
}
|
||||
|
||||
interfaces, _ := internal.Registry.GroupOrDie(internal.GroupName).InterfacesFor(version)
|
||||
if mapping.ObjectConvertor != interfaces.ObjectConvertor {
|
||||
t.Errorf("unexpected: %#v, expected: %#v", mapping, interfaces)
|
||||
}
|
||||
|
||||
rc := &internal.ReplicationController{ObjectMeta: metav1.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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestUnversioned(t *testing.T) {
|
||||
for _, obj := range []runtime.Object{
|
||||
&metav1.Status{},
|
||||
} {
|
||||
if unversioned, ok := internal.Scheme.IsUnversioned(obj); !unversioned || !ok {
|
||||
t.Errorf("%v is expected to be unversioned", reflect.TypeOf(obj))
|
||||
}
|
||||
}
|
||||
}
|
||||
28
vendor/k8s.io/kubernetes/pkg/api/json.go
generated
vendored
28
vendor/k8s.io/kubernetes/pkg/api/json.go
generated
vendored
|
|
@ -1,28 +0,0 @@
|
|||
/*
|
||||
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
|
||||
|
||||
import "encoding/json"
|
||||
|
||||
// This file implements json marshaling/unmarshaling interfaces on objects that are currently marshaled into annotations
|
||||
// to prevent anyone from marshaling these internal structs.
|
||||
|
||||
var _ = json.Marshaler(&AvoidPods{})
|
||||
var _ = json.Unmarshaler(&AvoidPods{})
|
||||
|
||||
func (AvoidPods) MarshalJSON() ([]byte, error) { panic("do not marshal internal struct") }
|
||||
func (*AvoidPods) UnmarshalJSON([]byte) error { panic("do not unmarshal to internal struct") }
|
||||
28
vendor/k8s.io/kubernetes/pkg/api/legacyscheme/BUILD
generated
vendored
Normal file
28
vendor/k8s.io/kubernetes/pkg/api/legacyscheme/BUILD
generated
vendored
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["scheme.go"],
|
||||
importpath = "k8s.io/kubernetes/pkg/api/legacyscheme",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//vendor/k8s.io/apimachinery/pkg/apimachinery/announced:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apimachinery/registered:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
46
vendor/k8s.io/kubernetes/pkg/api/legacyscheme/scheme.go
generated
vendored
Normal file
46
vendor/k8s.io/kubernetes/pkg/api/legacyscheme/scheme.go
generated
vendored
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
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 legacyscheme
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"k8s.io/apimachinery/pkg/apimachinery/announced"
|
||||
"k8s.io/apimachinery/pkg/apimachinery/registered"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/serializer"
|
||||
)
|
||||
|
||||
// GroupFactoryRegistry is the APIGroupFactoryRegistry (overlaps a bit with Registry, see comments in package for details)
|
||||
var GroupFactoryRegistry = make(announced.APIGroupFactoryRegistry)
|
||||
|
||||
// Registry is an instance of an API registry. This is an interim step to start removing the idea of a global
|
||||
// API registry.
|
||||
var Registry = registered.NewOrDie(os.Getenv("KUBE_API_VERSIONS"))
|
||||
|
||||
// Scheme is the default instance of runtime.Scheme to which types in the Kubernetes API are already registered.
|
||||
// NOTE: If you are copying this file to start a new api group, STOP! Copy the
|
||||
// extensions group instead. This Scheme is special and should appear ONLY in
|
||||
// the api group, unless you really know what you're doing.
|
||||
// TODO(lavalamp): make the above error impossible.
|
||||
var Scheme = runtime.NewScheme()
|
||||
|
||||
// Codecs provides access to encoding and decoding for the scheme
|
||||
var Codecs = serializer.NewCodecFactory(Scheme)
|
||||
|
||||
// ParameterCodec handles versioning of objects that are converted to query parameters.
|
||||
var ParameterCodec = runtime.NewParameterCodec(Scheme)
|
||||
103
vendor/k8s.io/kubernetes/pkg/api/meta_test.go
generated
vendored
103
vendor/k8s.io/kubernetes/pkg/api/meta_test.go
generated
vendored
|
|
@ -1,103 +0,0 @@
|
|||
/*
|
||||
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
49
vendor/k8s.io/kubernetes/pkg/api/node_example.json
generated
vendored
|
|
@ -1,49 +0,0 @@
|
|||
{
|
||||
"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"
|
||||
}
|
||||
}
|
||||
}
|
||||
34
vendor/k8s.io/kubernetes/pkg/api/objectreference.go
generated
vendored
34
vendor/k8s.io/kubernetes/pkg/api/objectreference.go
generated
vendored
|
|
@ -1,34 +0,0 @@
|
|||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
//TODO: consider making these methods functions, because we don't want helper
|
||||
//functions in the k8s.io/api repo.
|
||||
|
||||
package api
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
)
|
||||
|
||||
func (obj *ObjectReference) SetGroupVersionKind(gvk schema.GroupVersionKind) {
|
||||
obj.APIVersion, obj.Kind = gvk.ToAPIVersionAndKind()
|
||||
}
|
||||
|
||||
func (obj *ObjectReference) GroupVersionKind() schema.GroupVersionKind {
|
||||
return schema.FromAPIVersionAndKind(obj.APIVersion, obj.Kind)
|
||||
}
|
||||
|
||||
func (obj *ObjectReference) GetObjectKind() schema.ObjectKind { return obj }
|
||||
124
vendor/k8s.io/kubernetes/pkg/api/register.go
generated
vendored
124
vendor/k8s.io/kubernetes/pkg/api/register.go
generated
vendored
|
|
@ -1,124 +0,0 @@
|
|||
/*
|
||||
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
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"k8s.io/apimachinery/pkg/apimachinery/announced"
|
||||
"k8s.io/apimachinery/pkg/apimachinery/registered"
|
||||
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"
|
||||
)
|
||||
|
||||
// GroupFactoryRegistry is the APIGroupFactoryRegistry (overlaps a bit with Registry, see comments in package for details)
|
||||
var GroupFactoryRegistry = make(announced.APIGroupFactoryRegistry)
|
||||
|
||||
// Registry is an instance of an API registry. This is an interim step to start removing the idea of a global
|
||||
// API registry.
|
||||
var Registry = registered.NewOrDie(os.Getenv("KUBE_API_VERSIONS"))
|
||||
|
||||
// Scheme is the default instance of runtime.Scheme to which types in the Kubernetes API are already registered.
|
||||
// NOTE: If you are copying this file to start a new api group, STOP! Copy the
|
||||
// extensions group instead. This Scheme is special and should appear ONLY in
|
||||
// the api group, unless you really know what you're doing.
|
||||
// TODO(lavalamp): make the above error impossible.
|
||||
var Scheme = runtime.NewScheme()
|
||||
|
||||
// Codecs provides access to encoding and decoding for the scheme
|
||||
var Codecs = serializer.NewCodecFactory(Scheme)
|
||||
|
||||
// GroupName is the group name use in this package
|
||||
const GroupName = ""
|
||||
|
||||
// SchemeGroupVersion is group version used to register these objects
|
||||
var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: runtime.APIVersionInternal}
|
||||
|
||||
// ParameterCodec handles versioning of objects that are converted to query parameters.
|
||||
var ParameterCodec = runtime.NewParameterCodec(Scheme)
|
||||
|
||||
// Kind takes an unqualified kind and returns a Group qualified GroupKind
|
||||
func Kind(kind string) schema.GroupKind {
|
||||
return SchemeGroupVersion.WithKind(kind).GroupKind()
|
||||
}
|
||||
|
||||
// Resource takes an unqualified resource and returns a Group qualified GroupResource
|
||||
func Resource(resource string) schema.GroupResource {
|
||||
return SchemeGroupVersion.WithResource(resource).GroupResource()
|
||||
}
|
||||
|
||||
var (
|
||||
SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes)
|
||||
AddToScheme = SchemeBuilder.AddToScheme
|
||||
)
|
||||
|
||||
func addKnownTypes(scheme *runtime.Scheme) error {
|
||||
if err := scheme.AddIgnoredConversionType(&metav1.TypeMeta{}, &metav1.TypeMeta{}); err != nil {
|
||||
return err
|
||||
}
|
||||
scheme.AddKnownTypes(SchemeGroupVersion,
|
||||
&Pod{},
|
||||
&PodList{},
|
||||
&PodStatusResult{},
|
||||
&PodTemplate{},
|
||||
&PodTemplateList{},
|
||||
&ReplicationControllerList{},
|
||||
&ReplicationController{},
|
||||
&ServiceList{},
|
||||
&Service{},
|
||||
&ServiceProxyOptions{},
|
||||
&NodeList{},
|
||||
&Node{},
|
||||
&NodeConfigSource{},
|
||||
&NodeProxyOptions{},
|
||||
&Endpoints{},
|
||||
&EndpointsList{},
|
||||
&Binding{},
|
||||
&Event{},
|
||||
&EventList{},
|
||||
&List{},
|
||||
&LimitRange{},
|
||||
&LimitRangeList{},
|
||||
&ResourceQuota{},
|
||||
&ResourceQuotaList{},
|
||||
&Namespace{},
|
||||
&NamespaceList{},
|
||||
&ServiceAccount{},
|
||||
&ServiceAccountList{},
|
||||
&Secret{},
|
||||
&SecretList{},
|
||||
&PersistentVolume{},
|
||||
&PersistentVolumeList{},
|
||||
&PersistentVolumeClaim{},
|
||||
&PersistentVolumeClaimList{},
|
||||
&PodAttachOptions{},
|
||||
&PodLogOptions{},
|
||||
&PodExecOptions{},
|
||||
&PodPortForwardOptions{},
|
||||
&PodProxyOptions{},
|
||||
&ComponentStatus{},
|
||||
&ComponentStatusList{},
|
||||
&SerializedReference{},
|
||||
&RangeAllocation{},
|
||||
&ConfigMap{},
|
||||
&ConfigMapList{},
|
||||
)
|
||||
|
||||
return nil
|
||||
}
|
||||
83
vendor/k8s.io/kubernetes/pkg/api/replication_controller_example.json
generated
vendored
83
vendor/k8s.io/kubernetes/pkg/api/replication_controller_example.json
generated
vendored
|
|
@ -1,83 +0,0 @@
|
|||
{
|
||||
"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
|
||||
}
|
||||
}
|
||||
62
vendor/k8s.io/kubernetes/pkg/api/resource.go
generated
vendored
62
vendor/k8s.io/kubernetes/pkg/api/resource.go
generated
vendored
|
|
@ -1,62 +0,0 @@
|
|||
/*
|
||||
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
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
)
|
||||
|
||||
func (self ResourceName) String() string {
|
||||
return string(self)
|
||||
}
|
||||
|
||||
// Returns the CPU limit if specified.
|
||||
func (self *ResourceList) Cpu() *resource.Quantity {
|
||||
if val, ok := (*self)[ResourceCPU]; ok {
|
||||
return &val
|
||||
}
|
||||
return &resource.Quantity{Format: resource.DecimalSI}
|
||||
}
|
||||
|
||||
// Returns the Memory limit if specified.
|
||||
func (self *ResourceList) Memory() *resource.Quantity {
|
||||
if val, ok := (*self)[ResourceMemory]; ok {
|
||||
return &val
|
||||
}
|
||||
return &resource.Quantity{Format: resource.BinarySI}
|
||||
}
|
||||
|
||||
func (self *ResourceList) Pods() *resource.Quantity {
|
||||
if val, ok := (*self)[ResourcePods]; ok {
|
||||
return &val
|
||||
}
|
||||
return &resource.Quantity{}
|
||||
}
|
||||
|
||||
func (self *ResourceList) NvidiaGPU() *resource.Quantity {
|
||||
if val, ok := (*self)[ResourceNvidiaGPU]; ok {
|
||||
return &val
|
||||
}
|
||||
return &resource.Quantity{}
|
||||
}
|
||||
|
||||
func (self *ResourceList) StorageEphemeral() *resource.Quantity {
|
||||
if val, ok := (*self)[ResourceEphemeralStorage]; ok {
|
||||
return &val
|
||||
}
|
||||
return &resource.Quantity{}
|
||||
}
|
||||
217
vendor/k8s.io/kubernetes/pkg/api/serialization_proto_test.go
generated
vendored
217
vendor/k8s.io/kubernetes/pkg/api/serialization_proto_test.go
generated
vendored
|
|
@ -1,217 +0,0 @@
|
|||
/*
|
||||
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
561
vendor/k8s.io/kubernetes/pkg/api/serialization_test.go
generated
vendored
|
|
@ -1,561 +0,0 @@
|
|||
/*
|
||||
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()
|
||||
}
|
||||
6
vendor/k8s.io/kubernetes/pkg/api/service/BUILD
generated
vendored
6
vendor/k8s.io/kubernetes/pkg/api/service/BUILD
generated
vendored
|
|
@ -9,8 +9,9 @@ load(
|
|||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["util.go"],
|
||||
importpath = "k8s.io/kubernetes/pkg/api/service",
|
||||
deps = [
|
||||
"//pkg/api:go_default_library",
|
||||
"//pkg/apis/core:go_default_library",
|
||||
"//pkg/util/net/sets:go_default_library",
|
||||
],
|
||||
)
|
||||
|
|
@ -18,9 +19,10 @@ 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",
|
||||
"//pkg/apis/core:go_default_library",
|
||||
"//pkg/util/net/sets:go_default_library",
|
||||
],
|
||||
)
|
||||
|
|
|
|||
5
vendor/k8s.io/kubernetes/pkg/api/service/util.go
generated
vendored
5
vendor/k8s.io/kubernetes/pkg/api/service/util.go
generated
vendored
|
|
@ -18,10 +18,9 @@ package service
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
api "k8s.io/kubernetes/pkg/apis/core"
|
||||
netsets "k8s.io/kubernetes/pkg/util/net/sets"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
|
|||
2
vendor/k8s.io/kubernetes/pkg/api/service/util_test.go
generated
vendored
2
vendor/k8s.io/kubernetes/pkg/api/service/util_test.go
generated
vendored
|
|
@ -20,7 +20,7 @@ import (
|
|||
"strings"
|
||||
"testing"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
api "k8s.io/kubernetes/pkg/apis/core"
|
||||
netsets "k8s.io/kubernetes/pkg/util/net/sets"
|
||||
)
|
||||
|
||||
|
|
|
|||
36
vendor/k8s.io/kubernetes/pkg/api/taint.go
generated
vendored
36
vendor/k8s.io/kubernetes/pkg/api/taint.go
generated
vendored
|
|
@ -1,36 +0,0 @@
|
|||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
//TODO: consider making these methods functions, because we don't want helper
|
||||
//functions in the k8s.io/api repo.
|
||||
|
||||
package api
|
||||
|
||||
import "fmt"
|
||||
|
||||
// MatchTaint checks if the taint matches taintToMatch. Taints are unique by key:effect,
|
||||
// if the two taints have same key:effect, regard as they match.
|
||||
func (t *Taint) MatchTaint(taintToMatch Taint) bool {
|
||||
return t.Key == taintToMatch.Key && t.Effect == taintToMatch.Effect
|
||||
}
|
||||
|
||||
// taint.ToString() converts taint struct to string in format key=value:effect or key:effect.
|
||||
func (t *Taint) ToString() string {
|
||||
if len(t.Value) == 0 {
|
||||
return fmt.Sprintf("%v:%v", t.Key, t.Effect)
|
||||
}
|
||||
return fmt.Sprintf("%v=%v:%v", t.Key, t.Value, t.Effect)
|
||||
}
|
||||
120
vendor/k8s.io/kubernetes/pkg/api/taint_test.go
generated
vendored
120
vendor/k8s.io/kubernetes/pkg/api/taint_test.go
generated
vendored
|
|
@ -1,120 +0,0 @@
|
|||
/*
|
||||
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
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestTaintToString(t *testing.T) {
|
||||
testCases := []struct {
|
||||
taint *Taint
|
||||
expectedString string
|
||||
}{
|
||||
{
|
||||
taint: &Taint{
|
||||
Key: "foo",
|
||||
Value: "bar",
|
||||
Effect: TaintEffectNoSchedule,
|
||||
},
|
||||
expectedString: "foo=bar:NoSchedule",
|
||||
},
|
||||
{
|
||||
taint: &Taint{
|
||||
Key: "foo",
|
||||
Effect: TaintEffectNoSchedule,
|
||||
},
|
||||
expectedString: "foo:NoSchedule",
|
||||
},
|
||||
}
|
||||
|
||||
for i, tc := range testCases {
|
||||
if tc.expectedString != tc.taint.ToString() {
|
||||
t.Errorf("[%v] expected taint %v converted to %s, got %s", i, tc.taint, tc.expectedString, tc.taint.ToString())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestMatchTaint(t *testing.T) {
|
||||
testCases := []struct {
|
||||
description string
|
||||
taint *Taint
|
||||
taintToMatch Taint
|
||||
expectMatch bool
|
||||
}{
|
||||
{
|
||||
description: "two taints with the same key,value,effect should match",
|
||||
taint: &Taint{
|
||||
Key: "foo",
|
||||
Value: "bar",
|
||||
Effect: TaintEffectNoSchedule,
|
||||
},
|
||||
taintToMatch: Taint{
|
||||
Key: "foo",
|
||||
Value: "bar",
|
||||
Effect: TaintEffectNoSchedule,
|
||||
},
|
||||
expectMatch: true,
|
||||
},
|
||||
{
|
||||
description: "two taints with the same key,effect but different value should match",
|
||||
taint: &Taint{
|
||||
Key: "foo",
|
||||
Value: "bar",
|
||||
Effect: TaintEffectNoSchedule,
|
||||
},
|
||||
taintToMatch: Taint{
|
||||
Key: "foo",
|
||||
Value: "different-value",
|
||||
Effect: TaintEffectNoSchedule,
|
||||
},
|
||||
expectMatch: true,
|
||||
},
|
||||
{
|
||||
description: "two taints with the different key cannot match",
|
||||
taint: &Taint{
|
||||
Key: "foo",
|
||||
Value: "bar",
|
||||
Effect: TaintEffectNoSchedule,
|
||||
},
|
||||
taintToMatch: Taint{
|
||||
Key: "different-key",
|
||||
Value: "bar",
|
||||
Effect: TaintEffectNoSchedule,
|
||||
},
|
||||
expectMatch: false,
|
||||
},
|
||||
{
|
||||
description: "two taints with the different effect cannot match",
|
||||
taint: &Taint{
|
||||
Key: "foo",
|
||||
Value: "bar",
|
||||
Effect: TaintEffectNoSchedule,
|
||||
},
|
||||
taintToMatch: Taint{
|
||||
Key: "foo",
|
||||
Value: "bar",
|
||||
Effect: TaintEffectPreferNoSchedule,
|
||||
},
|
||||
expectMatch: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
if tc.expectMatch != tc.taint.MatchTaint(tc.taintToMatch) {
|
||||
t.Errorf("[%s] expect taint %s match taint %s", tc.description, tc.taint.ToString(), tc.taintToMatch.ToString())
|
||||
}
|
||||
}
|
||||
}
|
||||
30
vendor/k8s.io/kubernetes/pkg/api/toleration.go
generated
vendored
30
vendor/k8s.io/kubernetes/pkg/api/toleration.go
generated
vendored
|
|
@ -1,30 +0,0 @@
|
|||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
//TODO: consider making these methods functions, because we don't want helper
|
||||
//functions in the k8s.io/api repo.
|
||||
|
||||
package api
|
||||
|
||||
// MatchToleration checks if the toleration matches tolerationToMatch. Tolerations are unique by <key,effect,operator,value>,
|
||||
// if the two tolerations have same <key,effect,operator,value> combination, regard as they match.
|
||||
// TODO: uniqueness check for tolerations in api validations.
|
||||
func (t *Toleration) MatchToleration(tolerationToMatch *Toleration) bool {
|
||||
return t.Key == tolerationToMatch.Key &&
|
||||
t.Effect == tolerationToMatch.Effect &&
|
||||
t.Operator == tolerationToMatch.Operator &&
|
||||
t.Value == tolerationToMatch.Value
|
||||
}
|
||||
4287
vendor/k8s.io/kubernetes/pkg/api/types.go
generated
vendored
4287
vendor/k8s.io/kubernetes/pkg/api/types.go
generated
vendored
File diff suppressed because it is too large
Load diff
174
vendor/k8s.io/kubernetes/pkg/api/unstructured_test.go
generated
vendored
174
vendor/k8s.io/kubernetes/pkg/api/unstructured_test.go
generated
vendored
|
|
@ -1,174 +0,0 @@
|
|||
/*
|
||||
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
31
vendor/k8s.io/kubernetes/pkg/api/util/BUILD
generated
vendored
|
|
@ -1,31 +0,0 @@
|
|||
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
3
vendor/k8s.io/kubernetes/pkg/api/util/OWNERS
generated
vendored
|
|
@ -1,3 +0,0 @@
|
|||
reviewers:
|
||||
- caesarxuchao
|
||||
- david-mcmahon
|
||||
48
vendor/k8s.io/kubernetes/pkg/api/util/group_version.go
generated
vendored
48
vendor/k8s.io/kubernetes/pkg/api/util/group_version.go
generated
vendored
|
|
@ -1,48 +0,0 @@
|
|||
/*
|
||||
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
|
||||
}
|
||||
93
vendor/k8s.io/kubernetes/pkg/api/util/group_version_test.go
generated
vendored
93
vendor/k8s.io/kubernetes/pkg/api/util/group_version_test.go
generated
vendored
|
|
@ -1,93 +0,0 @@
|
|||
/*
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
82
vendor/k8s.io/kubernetes/pkg/api/v1/BUILD
generated
vendored
82
vendor/k8s.io/kubernetes/pkg/api/v1/BUILD
generated
vendored
|
|
@ -1,82 +0,0 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
"go_test",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"conversion.go",
|
||||
"defaults.go",
|
||||
"doc.go",
|
||||
"generate.go",
|
||||
"register.go",
|
||||
"zz_generated.conversion.go",
|
||||
"zz_generated.defaults.go",
|
||||
],
|
||||
deps = [
|
||||
"//pkg/api:go_default_library",
|
||||
"//pkg/apis/extensions:go_default_library",
|
||||
"//pkg/util/parsers:go_default_library",
|
||||
"//pkg/util/pointer:go_default_library",
|
||||
"//vendor/k8s.io/api/core/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/resource: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/runtime:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/types:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/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",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_xtest",
|
||||
srcs = [
|
||||
"backward_compatibility_test.go",
|
||||
"conversion_test.go",
|
||||
"defaults_test.go",
|
||||
],
|
||||
deps = [
|
||||
":go_default_library",
|
||||
"//pkg/api: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",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//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",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [
|
||||
":package-srcs",
|
||||
"//pkg/api/v1/endpoints:all-srcs",
|
||||
"//pkg/api/v1/helper:all-srcs",
|
||||
"//pkg/api/v1/node:all-srcs",
|
||||
"//pkg/api/v1/pod:all-srcs",
|
||||
"//pkg/api/v1/resource:all-srcs",
|
||||
"//pkg/api/v1/service:all-srcs",
|
||||
"//pkg/api/v1/validation:all-srcs",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
169
vendor/k8s.io/kubernetes/pkg/api/v1/backward_compatibility_test.go
generated
vendored
169
vendor/k8s.io/kubernetes/pkg/api/v1/backward_compatibility_test.go
generated
vendored
|
|
@ -1,169 +0,0 @@
|
|||
/*
|
||||
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)
|
||||
}
|
||||
}
|
||||
556
vendor/k8s.io/kubernetes/pkg/api/v1/conversion.go
generated
vendored
556
vendor/k8s.io/kubernetes/pkg/api/v1/conversion.go
generated
vendored
|
|
@ -1,556 +0,0 @@
|
|||
/*
|
||||
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
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/conversion"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
)
|
||||
|
||||
// This is a "fast-path" that avoids reflection for common types. It focuses on the objects that are
|
||||
// converted the most in the cluster.
|
||||
// TODO: generate one of these for every external API group - this is to prove the impact
|
||||
func addFastPathConversionFuncs(scheme *runtime.Scheme) error {
|
||||
scheme.AddGenericConversionFunc(func(objA, objB interface{}, s conversion.Scope) (bool, error) {
|
||||
switch a := objA.(type) {
|
||||
case *v1.Pod:
|
||||
switch b := objB.(type) {
|
||||
case *api.Pod:
|
||||
return true, Convert_v1_Pod_To_api_Pod(a, b, s)
|
||||
}
|
||||
case *api.Pod:
|
||||
switch b := objB.(type) {
|
||||
case *v1.Pod:
|
||||
return true, Convert_api_Pod_To_v1_Pod(a, b, s)
|
||||
}
|
||||
|
||||
case *v1.Event:
|
||||
switch b := objB.(type) {
|
||||
case *api.Event:
|
||||
return true, Convert_v1_Event_To_api_Event(a, b, s)
|
||||
}
|
||||
case *api.Event:
|
||||
switch b := objB.(type) {
|
||||
case *v1.Event:
|
||||
return true, Convert_api_Event_To_v1_Event(a, b, s)
|
||||
}
|
||||
|
||||
case *v1.ReplicationController:
|
||||
switch b := objB.(type) {
|
||||
case *api.ReplicationController:
|
||||
return true, Convert_v1_ReplicationController_To_api_ReplicationController(a, b, s)
|
||||
}
|
||||
case *api.ReplicationController:
|
||||
switch b := objB.(type) {
|
||||
case *v1.ReplicationController:
|
||||
return true, Convert_api_ReplicationController_To_v1_ReplicationController(a, b, s)
|
||||
}
|
||||
|
||||
case *v1.Node:
|
||||
switch b := objB.(type) {
|
||||
case *api.Node:
|
||||
return true, Convert_v1_Node_To_api_Node(a, b, s)
|
||||
}
|
||||
case *api.Node:
|
||||
switch b := objB.(type) {
|
||||
case *v1.Node:
|
||||
return true, Convert_api_Node_To_v1_Node(a, b, s)
|
||||
}
|
||||
|
||||
case *v1.Namespace:
|
||||
switch b := objB.(type) {
|
||||
case *api.Namespace:
|
||||
return true, Convert_v1_Namespace_To_api_Namespace(a, b, s)
|
||||
}
|
||||
case *api.Namespace:
|
||||
switch b := objB.(type) {
|
||||
case *v1.Namespace:
|
||||
return true, Convert_api_Namespace_To_v1_Namespace(a, b, s)
|
||||
}
|
||||
|
||||
case *v1.Service:
|
||||
switch b := objB.(type) {
|
||||
case *api.Service:
|
||||
return true, Convert_v1_Service_To_api_Service(a, b, s)
|
||||
}
|
||||
case *api.Service:
|
||||
switch b := objB.(type) {
|
||||
case *v1.Service:
|
||||
return true, Convert_api_Service_To_v1_Service(a, b, s)
|
||||
}
|
||||
|
||||
case *v1.Endpoints:
|
||||
switch b := objB.(type) {
|
||||
case *api.Endpoints:
|
||||
return true, Convert_v1_Endpoints_To_api_Endpoints(a, b, s)
|
||||
}
|
||||
case *api.Endpoints:
|
||||
switch b := objB.(type) {
|
||||
case *v1.Endpoints:
|
||||
return true, Convert_api_Endpoints_To_v1_Endpoints(a, b, s)
|
||||
}
|
||||
|
||||
case *metav1.WatchEvent:
|
||||
switch b := objB.(type) {
|
||||
case *metav1.InternalEvent:
|
||||
return true, metav1.Convert_versioned_Event_to_versioned_InternalEvent(a, b, s)
|
||||
}
|
||||
case *metav1.InternalEvent:
|
||||
switch b := objB.(type) {
|
||||
case *metav1.WatchEvent:
|
||||
return true, metav1.Convert_versioned_InternalEvent_to_versioned_Event(a, b, s)
|
||||
}
|
||||
}
|
||||
return false, nil
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
func addConversionFuncs(scheme *runtime.Scheme) error {
|
||||
// Add non-generated conversion functions
|
||||
err := scheme.AddConversionFuncs(
|
||||
Convert_api_Pod_To_v1_Pod,
|
||||
Convert_api_PodSpec_To_v1_PodSpec,
|
||||
Convert_api_ReplicationControllerSpec_To_v1_ReplicationControllerSpec,
|
||||
Convert_api_ServiceSpec_To_v1_ServiceSpec,
|
||||
Convert_v1_Pod_To_api_Pod,
|
||||
Convert_v1_PodSpec_To_api_PodSpec,
|
||||
Convert_v1_ReplicationControllerSpec_To_api_ReplicationControllerSpec,
|
||||
Convert_v1_Secret_To_api_Secret,
|
||||
Convert_v1_ServiceSpec_To_api_ServiceSpec,
|
||||
Convert_v1_ResourceList_To_api_ResourceList,
|
||||
Convert_v1_ReplicationController_to_extensions_ReplicaSet,
|
||||
Convert_v1_ReplicationControllerSpec_to_extensions_ReplicaSetSpec,
|
||||
Convert_v1_ReplicationControllerStatus_to_extensions_ReplicaSetStatus,
|
||||
Convert_extensions_ReplicaSet_to_v1_ReplicationController,
|
||||
Convert_extensions_ReplicaSetSpec_to_v1_ReplicationControllerSpec,
|
||||
Convert_extensions_ReplicaSetStatus_to_v1_ReplicationControllerStatus,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Add field conversion funcs.
|
||||
err = scheme.AddFieldLabelConversionFunc("v1", "Pod",
|
||||
func(label, value string) (string, string, error) {
|
||||
switch label {
|
||||
case "metadata.annotations",
|
||||
"metadata.labels",
|
||||
"metadata.name",
|
||||
"metadata.namespace",
|
||||
"metadata.uid",
|
||||
"spec.nodeName",
|
||||
"spec.restartPolicy",
|
||||
"spec.serviceAccountName",
|
||||
"spec.schedulerName",
|
||||
"status.phase",
|
||||
"status.hostIP",
|
||||
"status.podIP":
|
||||
return label, value, nil
|
||||
// This is for backwards compatibility with old v1 clients which send spec.host
|
||||
case "spec.host":
|
||||
return "spec.nodeName", value, nil
|
||||
default:
|
||||
return "", "", fmt.Errorf("field label not supported: %s", label)
|
||||
}
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = scheme.AddFieldLabelConversionFunc("v1", "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 {
|
||||
return err
|
||||
}
|
||||
err = scheme.AddFieldLabelConversionFunc("v1", "ReplicationController",
|
||||
func(label, value string) (string, string, error) {
|
||||
switch label {
|
||||
case "metadata.name",
|
||||
"metadata.namespace",
|
||||
"status.replicas":
|
||||
return label, value, nil
|
||||
default:
|
||||
return "", "", fmt.Errorf("field label not supported: %s", label)
|
||||
}
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := AddFieldLabelConversionsForEvent(scheme); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := AddFieldLabelConversionsForNamespace(scheme); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := AddFieldLabelConversionsForSecret(scheme); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_v1_ReplicationController_to_extensions_ReplicaSet(in *v1.ReplicationController, out *extensions.ReplicaSet, s conversion.Scope) error {
|
||||
out.ObjectMeta = in.ObjectMeta
|
||||
if err := Convert_v1_ReplicationControllerSpec_to_extensions_ReplicaSetSpec(&in.Spec, &out.Spec, s); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := Convert_v1_ReplicationControllerStatus_to_extensions_ReplicaSetStatus(&in.Status, &out.Status, s); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_v1_ReplicationControllerSpec_to_extensions_ReplicaSetSpec(in *v1.ReplicationControllerSpec, out *extensions.ReplicaSetSpec, s conversion.Scope) error {
|
||||
out.Replicas = *in.Replicas
|
||||
if in.Selector != nil {
|
||||
metav1.Convert_map_to_unversioned_LabelSelector(&in.Selector, out.Selector, s)
|
||||
}
|
||||
if in.Template != nil {
|
||||
if err := Convert_v1_PodTemplateSpec_To_api_PodTemplateSpec(in.Template, &out.Template, s); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_v1_ReplicationControllerStatus_to_extensions_ReplicaSetStatus(in *v1.ReplicationControllerStatus, out *extensions.ReplicaSetStatus, s conversion.Scope) error {
|
||||
out.Replicas = in.Replicas
|
||||
out.FullyLabeledReplicas = in.FullyLabeledReplicas
|
||||
out.ReadyReplicas = in.ReadyReplicas
|
||||
out.AvailableReplicas = in.AvailableReplicas
|
||||
out.ObservedGeneration = in.ObservedGeneration
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_extensions_ReplicaSet_to_v1_ReplicationController(in *extensions.ReplicaSet, out *v1.ReplicationController, s conversion.Scope) error {
|
||||
out.ObjectMeta = in.ObjectMeta
|
||||
if err := Convert_extensions_ReplicaSetSpec_to_v1_ReplicationControllerSpec(&in.Spec, &out.Spec, s); err != nil {
|
||||
fieldErr, ok := err.(*field.Error)
|
||||
if !ok {
|
||||
return err
|
||||
}
|
||||
if out.Annotations == nil {
|
||||
out.Annotations = make(map[string]string)
|
||||
}
|
||||
out.Annotations[v1.NonConvertibleAnnotationPrefix+"/"+fieldErr.Field] = reflect.ValueOf(fieldErr.BadValue).String()
|
||||
}
|
||||
if err := Convert_extensions_ReplicaSetStatus_to_v1_ReplicationControllerStatus(&in.Status, &out.Status, s); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_extensions_ReplicaSetSpec_to_v1_ReplicationControllerSpec(in *extensions.ReplicaSetSpec, out *v1.ReplicationControllerSpec, s conversion.Scope) error {
|
||||
out.Replicas = new(int32)
|
||||
*out.Replicas = in.Replicas
|
||||
out.MinReadySeconds = in.MinReadySeconds
|
||||
var invalidErr error
|
||||
if in.Selector != nil {
|
||||
invalidErr = metav1.Convert_unversioned_LabelSelector_to_map(in.Selector, &out.Selector, s)
|
||||
}
|
||||
out.Template = new(v1.PodTemplateSpec)
|
||||
if err := Convert_api_PodTemplateSpec_To_v1_PodTemplateSpec(&in.Template, out.Template, s); err != nil {
|
||||
return err
|
||||
}
|
||||
return invalidErr
|
||||
}
|
||||
|
||||
func Convert_extensions_ReplicaSetStatus_to_v1_ReplicationControllerStatus(in *extensions.ReplicaSetStatus, out *v1.ReplicationControllerStatus, s conversion.Scope) error {
|
||||
out.Replicas = in.Replicas
|
||||
out.FullyLabeledReplicas = in.FullyLabeledReplicas
|
||||
out.ReadyReplicas = in.ReadyReplicas
|
||||
out.AvailableReplicas = in.AvailableReplicas
|
||||
out.ObservedGeneration = in.ObservedGeneration
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_api_ReplicationControllerSpec_To_v1_ReplicationControllerSpec(in *api.ReplicationControllerSpec, out *v1.ReplicationControllerSpec, s conversion.Scope) error {
|
||||
out.Replicas = &in.Replicas
|
||||
out.MinReadySeconds = in.MinReadySeconds
|
||||
out.Selector = in.Selector
|
||||
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_v1_ReplicationControllerSpec_To_api_ReplicationControllerSpec(in *v1.ReplicationControllerSpec, out *api.ReplicationControllerSpec, s conversion.Scope) error {
|
||||
if in.Replicas != nil {
|
||||
out.Replicas = *in.Replicas
|
||||
}
|
||||
out.MinReadySeconds = in.MinReadySeconds
|
||||
out.Selector = in.Selector
|
||||
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_api_PodTemplateSpec_To_v1_PodTemplateSpec(in *api.PodTemplateSpec, out *v1.PodTemplateSpec, s conversion.Scope) error {
|
||||
if err := autoConvert_api_PodTemplateSpec_To_v1_PodTemplateSpec(in, out, s); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_v1_PodTemplateSpec_To_api_PodTemplateSpec(in *v1.PodTemplateSpec, out *api.PodTemplateSpec, s conversion.Scope) error {
|
||||
if err := autoConvert_v1_PodTemplateSpec_To_api_PodTemplateSpec(in, out, s); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// The following two v1.PodSpec conversions are done here to support v1.ServiceAccount
|
||||
// as an alias for ServiceAccountName.
|
||||
func Convert_api_PodSpec_To_v1_PodSpec(in *api.PodSpec, out *v1.PodSpec, s conversion.Scope) error {
|
||||
if err := autoConvert_api_PodSpec_To_v1_PodSpec(in, out, s); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// DeprecatedServiceAccount is an alias for ServiceAccountName.
|
||||
out.DeprecatedServiceAccount = in.ServiceAccountName
|
||||
|
||||
if in.SecurityContext != nil {
|
||||
// the host namespace fields have to be handled here for backward compatibility
|
||||
// with v1.0.0
|
||||
out.HostPID = in.SecurityContext.HostPID
|
||||
out.HostNetwork = in.SecurityContext.HostNetwork
|
||||
out.HostIPC = in.SecurityContext.HostIPC
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_v1_PodSpec_To_api_PodSpec(in *v1.PodSpec, out *api.PodSpec, s conversion.Scope) error {
|
||||
if err := autoConvert_v1_PodSpec_To_api_PodSpec(in, out, s); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// We support DeprecatedServiceAccount as an alias for ServiceAccountName.
|
||||
// If both are specified, ServiceAccountName (the new field) wins.
|
||||
if in.ServiceAccountName == "" {
|
||||
out.ServiceAccountName = in.DeprecatedServiceAccount
|
||||
}
|
||||
|
||||
// the host namespace fields have to be handled specially for backward compatibility
|
||||
// with v1.0.0
|
||||
if out.SecurityContext == nil {
|
||||
out.SecurityContext = new(api.PodSecurityContext)
|
||||
}
|
||||
out.SecurityContext.HostNetwork = in.HostNetwork
|
||||
out.SecurityContext.HostPID = in.HostPID
|
||||
out.SecurityContext.HostIPC = in.HostIPC
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_api_Pod_To_v1_Pod(in *api.Pod, out *v1.Pod, s conversion.Scope) error {
|
||||
if err := autoConvert_api_Pod_To_v1_Pod(in, out, s); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// drop init container annotations so they don't take effect on legacy kubelets.
|
||||
// remove this once the oldest supported kubelet no longer honors the annotations over the field.
|
||||
if len(out.Annotations) > 0 {
|
||||
old := out.Annotations
|
||||
out.Annotations = make(map[string]string, len(old))
|
||||
for k, v := range old {
|
||||
out.Annotations[k] = v
|
||||
}
|
||||
delete(out.Annotations, "pod.beta.kubernetes.io/init-containers")
|
||||
delete(out.Annotations, "pod.alpha.kubernetes.io/init-containers")
|
||||
delete(out.Annotations, "pod.beta.kubernetes.io/init-container-statuses")
|
||||
delete(out.Annotations, "pod.alpha.kubernetes.io/init-container-statuses")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_v1_Secret_To_api_Secret(in *v1.Secret, out *api.Secret, s conversion.Scope) error {
|
||||
if err := autoConvert_v1_Secret_To_api_Secret(in, out, s); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// StringData overwrites Data
|
||||
if len(in.StringData) > 0 {
|
||||
if out.Data == nil {
|
||||
out.Data = map[string][]byte{}
|
||||
}
|
||||
for k, v := range in.StringData {
|
||||
out.Data[k] = []byte(v)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
func Convert_api_SecurityContext_To_v1_SecurityContext(in *api.SecurityContext, out *v1.SecurityContext, s conversion.Scope) error {
|
||||
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
|
||||
}
|
||||
out.Privileged = in.Privileged
|
||||
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
|
||||
}
|
||||
out.RunAsUser = in.RunAsUser
|
||||
out.RunAsNonRoot = in.RunAsNonRoot
|
||||
out.ReadOnlyRootFilesystem = in.ReadOnlyRootFilesystem
|
||||
out.AllowPrivilegeEscalation = in.AllowPrivilegeEscalation
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_api_PodSecurityContext_To_v1_PodSecurityContext(in *api.PodSecurityContext, out *v1.PodSecurityContext, s conversion.Scope) error {
|
||||
out.SupplementalGroups = in.SupplementalGroups
|
||||
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
|
||||
}
|
||||
out.RunAsUser = in.RunAsUser
|
||||
out.RunAsNonRoot = in.RunAsNonRoot
|
||||
out.FSGroup = in.FSGroup
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_v1_PodSecurityContext_To_api_PodSecurityContext(in *v1.PodSecurityContext, out *api.PodSecurityContext, s conversion.Scope) error {
|
||||
out.SupplementalGroups = in.SupplementalGroups
|
||||
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
|
||||
}
|
||||
out.RunAsUser = in.RunAsUser
|
||||
out.RunAsNonRoot = in.RunAsNonRoot
|
||||
out.FSGroup = in.FSGroup
|
||||
return nil
|
||||
}
|
||||
|
||||
// +k8s:conversion-fn=copy-only
|
||||
func Convert_v1_ResourceList_To_api_ResourceList(in *v1.ResourceList, out *api.ResourceList, s conversion.Scope) error {
|
||||
if *in == nil {
|
||||
return nil
|
||||
}
|
||||
if *out == nil {
|
||||
*out = make(api.ResourceList, len(*in))
|
||||
}
|
||||
for key, val := range *in {
|
||||
// Moved to defaults
|
||||
// TODO(#18538): We round up resource values to milli scale to maintain API compatibility.
|
||||
// In the future, we should instead reject values that need rounding.
|
||||
// const milliScale = -3
|
||||
// val.RoundUp(milliScale)
|
||||
|
||||
(*out)[api.ResourceName(key)] = val
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func AddFieldLabelConversionsForEvent(scheme *runtime.Scheme) error {
|
||||
return scheme.AddFieldLabelConversionFunc("v1", "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",
|
||||
"type",
|
||||
"metadata.namespace",
|
||||
"metadata.name":
|
||||
return label, value, nil
|
||||
default:
|
||||
return "", "", fmt.Errorf("field label not supported: %s", label)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func AddFieldLabelConversionsForNamespace(scheme *runtime.Scheme) error {
|
||||
return scheme.AddFieldLabelConversionFunc("v1", "Namespace",
|
||||
func(label, value string) (string, string, error) {
|
||||
switch label {
|
||||
case "status.phase",
|
||||
"metadata.name":
|
||||
return label, value, nil
|
||||
default:
|
||||
return "", "", fmt.Errorf("field label not supported: %s", label)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func AddFieldLabelConversionsForSecret(scheme *runtime.Scheme) error {
|
||||
return scheme.AddFieldLabelConversionFunc("v1", "Secret",
|
||||
func(label, value string) (string, string, error) {
|
||||
switch label {
|
||||
case "type",
|
||||
"metadata.namespace",
|
||||
"metadata.name":
|
||||
return label, value, nil
|
||||
default:
|
||||
return "", "", fmt.Errorf("field label not supported: %s", label)
|
||||
}
|
||||
})
|
||||
}
|
||||
224
vendor/k8s.io/kubernetes/pkg/api/v1/conversion_test.go
generated
vendored
224
vendor/k8s.io/kubernetes/pkg/api/v1/conversion_test.go
generated
vendored
|
|
@ -1,224 +0,0 @@
|
|||
/*
|
||||
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 (
|
||||
"net/url"
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
apiequality "k8s.io/apimachinery/pkg/api/equality"
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/util/diff"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
k8s_api_v1 "k8s.io/kubernetes/pkg/api/v1"
|
||||
)
|
||||
|
||||
func TestPodLogOptions(t *testing.T) {
|
||||
sinceSeconds := int64(1)
|
||||
sinceTime := metav1.NewTime(time.Date(2000, 1, 1, 12, 34, 56, 0, time.UTC).Local())
|
||||
tailLines := int64(2)
|
||||
limitBytes := int64(3)
|
||||
|
||||
versionedLogOptions := &v1.PodLogOptions{
|
||||
Container: "mycontainer",
|
||||
Follow: true,
|
||||
Previous: true,
|
||||
SinceSeconds: &sinceSeconds,
|
||||
SinceTime: &sinceTime,
|
||||
Timestamps: true,
|
||||
TailLines: &tailLines,
|
||||
LimitBytes: &limitBytes,
|
||||
}
|
||||
unversionedLogOptions := &api.PodLogOptions{
|
||||
Container: "mycontainer",
|
||||
Follow: true,
|
||||
Previous: true,
|
||||
SinceSeconds: &sinceSeconds,
|
||||
SinceTime: &sinceTime,
|
||||
Timestamps: true,
|
||||
TailLines: &tailLines,
|
||||
LimitBytes: &limitBytes,
|
||||
}
|
||||
expectedParameters := url.Values{
|
||||
"container": {"mycontainer"},
|
||||
"follow": {"true"},
|
||||
"previous": {"true"},
|
||||
"sinceSeconds": {"1"},
|
||||
"sinceTime": {"2000-01-01T12:34:56Z"},
|
||||
"timestamps": {"true"},
|
||||
"tailLines": {"2"},
|
||||
"limitBytes": {"3"},
|
||||
}
|
||||
|
||||
codec := runtime.NewParameterCodec(api.Scheme)
|
||||
|
||||
// unversioned -> query params
|
||||
{
|
||||
actualParameters, err := codec.EncodeParameters(unversionedLogOptions, v1.SchemeGroupVersion)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !reflect.DeepEqual(actualParameters, expectedParameters) {
|
||||
t.Fatalf("Expected\n%#v\ngot\n%#v", expectedParameters, actualParameters)
|
||||
}
|
||||
}
|
||||
|
||||
// versioned -> query params
|
||||
{
|
||||
actualParameters, err := codec.EncodeParameters(versionedLogOptions, v1.SchemeGroupVersion)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !reflect.DeepEqual(actualParameters, expectedParameters) {
|
||||
t.Fatalf("Expected\n%#v\ngot\n%#v", expectedParameters, actualParameters)
|
||||
}
|
||||
}
|
||||
|
||||
// query params -> versioned
|
||||
{
|
||||
convertedLogOptions := &v1.PodLogOptions{}
|
||||
err := codec.DecodeParameters(expectedParameters, v1.SchemeGroupVersion, convertedLogOptions)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !reflect.DeepEqual(convertedLogOptions, versionedLogOptions) {
|
||||
t.Fatalf("Unexpected deserialization:\n%s", diff.ObjectGoPrintSideBySide(versionedLogOptions, convertedLogOptions))
|
||||
}
|
||||
}
|
||||
|
||||
// query params -> unversioned
|
||||
{
|
||||
convertedLogOptions := &api.PodLogOptions{}
|
||||
err := codec.DecodeParameters(expectedParameters, v1.SchemeGroupVersion, convertedLogOptions)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !reflect.DeepEqual(convertedLogOptions, unversionedLogOptions) {
|
||||
t.Fatalf("Unexpected deserialization:\n%s", diff.ObjectGoPrintSideBySide(unversionedLogOptions, convertedLogOptions))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TestPodSpecConversion tests that v1.ServiceAccount is an alias for
|
||||
// ServiceAccountName.
|
||||
func TestPodSpecConversion(t *testing.T) {
|
||||
name, other := "foo", "bar"
|
||||
|
||||
// Test internal -> v1. Should have both alias (DeprecatedServiceAccount)
|
||||
// and new field (ServiceAccountName).
|
||||
i := &api.PodSpec{
|
||||
ServiceAccountName: name,
|
||||
}
|
||||
v := v1.PodSpec{}
|
||||
if err := api.Scheme.Convert(i, &v, nil); err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if v.ServiceAccountName != name {
|
||||
t.Fatalf("want v1.ServiceAccountName %q, got %q", name, v.ServiceAccountName)
|
||||
}
|
||||
if v.DeprecatedServiceAccount != name {
|
||||
t.Fatalf("want v1.DeprecatedServiceAccount %q, got %q", name, v.DeprecatedServiceAccount)
|
||||
}
|
||||
|
||||
// Test v1 -> internal. Either DeprecatedServiceAccount, ServiceAccountName,
|
||||
// or both should translate to ServiceAccountName. ServiceAccountName wins
|
||||
// if both are set.
|
||||
testCases := []*v1.PodSpec{
|
||||
// New
|
||||
{ServiceAccountName: name},
|
||||
// Alias
|
||||
{DeprecatedServiceAccount: name},
|
||||
// Both: same
|
||||
{ServiceAccountName: name, DeprecatedServiceAccount: name},
|
||||
// Both: different
|
||||
{ServiceAccountName: name, DeprecatedServiceAccount: other},
|
||||
}
|
||||
for k, v := range testCases {
|
||||
got := api.PodSpec{}
|
||||
err := api.Scheme.Convert(v, &got, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error for case %d: %v", k, err)
|
||||
}
|
||||
if got.ServiceAccountName != name {
|
||||
t.Fatalf("want api.ServiceAccountName %q, got %q", name, got.ServiceAccountName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestResourceListConversion(t *testing.T) {
|
||||
bigMilliQuantity := resource.NewQuantity(resource.MaxMilliValue, resource.DecimalSI)
|
||||
bigMilliQuantity.Add(resource.MustParse("12345m"))
|
||||
|
||||
tests := []struct {
|
||||
input v1.ResourceList
|
||||
expected api.ResourceList
|
||||
}{
|
||||
{ // No changes necessary.
|
||||
input: v1.ResourceList{
|
||||
v1.ResourceMemory: resource.MustParse("30M"),
|
||||
v1.ResourceCPU: resource.MustParse("100m"),
|
||||
v1.ResourceStorage: resource.MustParse("1G"),
|
||||
},
|
||||
expected: api.ResourceList{
|
||||
api.ResourceMemory: resource.MustParse("30M"),
|
||||
api.ResourceCPU: resource.MustParse("100m"),
|
||||
api.ResourceStorage: resource.MustParse("1G"),
|
||||
},
|
||||
},
|
||||
{ // Nano-scale values should be rounded up to milli-scale.
|
||||
input: v1.ResourceList{
|
||||
v1.ResourceCPU: resource.MustParse("3.000023m"),
|
||||
v1.ResourceMemory: resource.MustParse("500.000050m"),
|
||||
},
|
||||
expected: api.ResourceList{
|
||||
api.ResourceCPU: resource.MustParse("4m"),
|
||||
api.ResourceMemory: resource.MustParse("501m"),
|
||||
},
|
||||
},
|
||||
{ // Large values should still be accurate.
|
||||
input: v1.ResourceList{
|
||||
v1.ResourceCPU: *bigMilliQuantity.Copy(),
|
||||
v1.ResourceStorage: *bigMilliQuantity.Copy(),
|
||||
},
|
||||
expected: api.ResourceList{
|
||||
api.ResourceCPU: *bigMilliQuantity.Copy(),
|
||||
api.ResourceStorage: *bigMilliQuantity.Copy(),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for i, test := range tests {
|
||||
output := api.ResourceList{}
|
||||
|
||||
// defaulting is a separate step from conversion that is applied when reading from the API or from etcd.
|
||||
// perform that step explicitly.
|
||||
k8s_api_v1.SetDefaults_ResourceList(&test.input)
|
||||
|
||||
err := api.Scheme.Convert(&test.input, &output, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error for case %d: %v", i, err)
|
||||
}
|
||||
if !apiequality.Semantic.DeepEqual(test.expected, output) {
|
||||
t.Errorf("unexpected conversion for case %d: Expected\n%+v;\nGot\n%+v", i, test.expected, output)
|
||||
}
|
||||
}
|
||||
}
|
||||
391
vendor/k8s.io/kubernetes/pkg/api/v1/defaults.go
generated
vendored
391
vendor/k8s.io/kubernetes/pkg/api/v1/defaults.go
generated
vendored
|
|
@ -1,391 +0,0 @@
|
|||
/*
|
||||
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
|
||||
|
||||
import (
|
||||
"k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
"k8s.io/kubernetes/pkg/util/parsers"
|
||||
utilpointer "k8s.io/kubernetes/pkg/util/pointer"
|
||||
)
|
||||
|
||||
func addDefaultingFuncs(scheme *runtime.Scheme) error {
|
||||
return RegisterDefaults(scheme)
|
||||
}
|
||||
|
||||
func SetDefaults_ResourceList(obj *v1.ResourceList) {
|
||||
for key, val := range *obj {
|
||||
// TODO(#18538): We round up resource values to milli scale to maintain API compatibility.
|
||||
// In the future, we should instead reject values that need rounding.
|
||||
const milliScale = -3
|
||||
val.RoundUp(milliScale)
|
||||
|
||||
(*obj)[v1.ResourceName(key)] = val
|
||||
}
|
||||
}
|
||||
|
||||
func SetDefaults_PodExecOptions(obj *v1.PodExecOptions) {
|
||||
obj.Stdout = true
|
||||
obj.Stderr = true
|
||||
}
|
||||
func SetDefaults_PodAttachOptions(obj *v1.PodAttachOptions) {
|
||||
obj.Stdout = true
|
||||
obj.Stderr = true
|
||||
}
|
||||
func SetDefaults_ReplicationController(obj *v1.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(int32)
|
||||
*obj.Spec.Replicas = 1
|
||||
}
|
||||
}
|
||||
func SetDefaults_Volume(obj *v1.Volume) {
|
||||
if utilpointer.AllPtrFieldsNil(&obj.VolumeSource) {
|
||||
obj.VolumeSource = v1.VolumeSource{
|
||||
EmptyDir: &v1.EmptyDirVolumeSource{},
|
||||
}
|
||||
}
|
||||
}
|
||||
func SetDefaults_ContainerPort(obj *v1.ContainerPort) {
|
||||
if obj.Protocol == "" {
|
||||
obj.Protocol = v1.ProtocolTCP
|
||||
}
|
||||
}
|
||||
func SetDefaults_Container(obj *v1.Container) {
|
||||
if obj.ImagePullPolicy == "" {
|
||||
// Ignore error and assume it has been validated elsewhere
|
||||
_, tag, _, _ := parsers.ParseImageName(obj.Image)
|
||||
|
||||
// Check image tag
|
||||
if tag == "latest" {
|
||||
obj.ImagePullPolicy = v1.PullAlways
|
||||
} else {
|
||||
obj.ImagePullPolicy = v1.PullIfNotPresent
|
||||
}
|
||||
}
|
||||
if obj.TerminationMessagePath == "" {
|
||||
obj.TerminationMessagePath = v1.TerminationMessagePathDefault
|
||||
}
|
||||
if obj.TerminationMessagePolicy == "" {
|
||||
obj.TerminationMessagePolicy = v1.TerminationMessageReadFile
|
||||
}
|
||||
}
|
||||
func SetDefaults_Service(obj *v1.Service) {
|
||||
if obj.Spec.SessionAffinity == "" {
|
||||
obj.Spec.SessionAffinity = v1.ServiceAffinityNone
|
||||
}
|
||||
if obj.Spec.SessionAffinity == v1.ServiceAffinityNone {
|
||||
obj.Spec.SessionAffinityConfig = nil
|
||||
}
|
||||
if obj.Spec.SessionAffinity == v1.ServiceAffinityClientIP {
|
||||
if obj.Spec.SessionAffinityConfig == nil || obj.Spec.SessionAffinityConfig.ClientIP == nil || obj.Spec.SessionAffinityConfig.ClientIP.TimeoutSeconds == nil {
|
||||
timeoutSeconds := v1.DefaultClientIPServiceAffinitySeconds
|
||||
obj.Spec.SessionAffinityConfig = &v1.SessionAffinityConfig{
|
||||
ClientIP: &v1.ClientIPConfig{
|
||||
TimeoutSeconds: &timeoutSeconds,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
if obj.Spec.Type == "" {
|
||||
obj.Spec.Type = v1.ServiceTypeClusterIP
|
||||
}
|
||||
for i := range obj.Spec.Ports {
|
||||
sp := &obj.Spec.Ports[i]
|
||||
if sp.Protocol == "" {
|
||||
sp.Protocol = v1.ProtocolTCP
|
||||
}
|
||||
if sp.TargetPort == intstr.FromInt(0) || sp.TargetPort == intstr.FromString("") {
|
||||
sp.TargetPort = intstr.FromInt(int(sp.Port))
|
||||
}
|
||||
}
|
||||
// Defaults ExternalTrafficPolicy field for NodePort / LoadBalancer service
|
||||
// to Global for consistency.
|
||||
if (obj.Spec.Type == v1.ServiceTypeNodePort ||
|
||||
obj.Spec.Type == v1.ServiceTypeLoadBalancer) &&
|
||||
obj.Spec.ExternalTrafficPolicy == "" {
|
||||
obj.Spec.ExternalTrafficPolicy = v1.ServiceExternalTrafficPolicyTypeCluster
|
||||
}
|
||||
}
|
||||
func SetDefaults_Pod(obj *v1.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 v1.ResourceRequirements
|
||||
// because we only want this defaulting semantic to take place on a v1.Pod and not a v1.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(v1.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())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for i := range obj.Spec.InitContainers {
|
||||
if obj.Spec.InitContainers[i].Resources.Limits != nil {
|
||||
if obj.Spec.InitContainers[i].Resources.Requests == nil {
|
||||
obj.Spec.InitContainers[i].Resources.Requests = make(v1.ResourceList)
|
||||
}
|
||||
for key, value := range obj.Spec.InitContainers[i].Resources.Limits {
|
||||
if _, exists := obj.Spec.InitContainers[i].Resources.Requests[key]; !exists {
|
||||
obj.Spec.InitContainers[i].Resources.Requests[key] = *(value.Copy())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
func SetDefaults_PodSpec(obj *v1.PodSpec) {
|
||||
if obj.DNSPolicy == "" {
|
||||
obj.DNSPolicy = v1.DNSClusterFirst
|
||||
}
|
||||
if obj.RestartPolicy == "" {
|
||||
obj.RestartPolicy = v1.RestartPolicyAlways
|
||||
}
|
||||
if obj.HostNetwork {
|
||||
defaultHostNetworkPorts(&obj.Containers)
|
||||
defaultHostNetworkPorts(&obj.InitContainers)
|
||||
}
|
||||
if obj.SecurityContext == nil {
|
||||
obj.SecurityContext = &v1.PodSecurityContext{}
|
||||
}
|
||||
if obj.TerminationGracePeriodSeconds == nil {
|
||||
period := int64(v1.DefaultTerminationGracePeriodSeconds)
|
||||
obj.TerminationGracePeriodSeconds = &period
|
||||
}
|
||||
if obj.SchedulerName == "" {
|
||||
obj.SchedulerName = v1.DefaultSchedulerName
|
||||
}
|
||||
}
|
||||
func SetDefaults_Probe(obj *v1.Probe) {
|
||||
if obj.TimeoutSeconds == 0 {
|
||||
obj.TimeoutSeconds = 1
|
||||
}
|
||||
if obj.PeriodSeconds == 0 {
|
||||
obj.PeriodSeconds = 10
|
||||
}
|
||||
if obj.SuccessThreshold == 0 {
|
||||
obj.SuccessThreshold = 1
|
||||
}
|
||||
if obj.FailureThreshold == 0 {
|
||||
obj.FailureThreshold = 3
|
||||
}
|
||||
}
|
||||
func SetDefaults_SecretVolumeSource(obj *v1.SecretVolumeSource) {
|
||||
if obj.DefaultMode == nil {
|
||||
perm := int32(v1.SecretVolumeSourceDefaultMode)
|
||||
obj.DefaultMode = &perm
|
||||
}
|
||||
}
|
||||
func SetDefaults_ConfigMapVolumeSource(obj *v1.ConfigMapVolumeSource) {
|
||||
if obj.DefaultMode == nil {
|
||||
perm := int32(v1.ConfigMapVolumeSourceDefaultMode)
|
||||
obj.DefaultMode = &perm
|
||||
}
|
||||
}
|
||||
func SetDefaults_DownwardAPIVolumeSource(obj *v1.DownwardAPIVolumeSource) {
|
||||
if obj.DefaultMode == nil {
|
||||
perm := int32(v1.DownwardAPIVolumeSourceDefaultMode)
|
||||
obj.DefaultMode = &perm
|
||||
}
|
||||
}
|
||||
func SetDefaults_Secret(obj *v1.Secret) {
|
||||
if obj.Type == "" {
|
||||
obj.Type = v1.SecretTypeOpaque
|
||||
}
|
||||
}
|
||||
func SetDefaults_ProjectedVolumeSource(obj *v1.ProjectedVolumeSource) {
|
||||
if obj.DefaultMode == nil {
|
||||
perm := int32(v1.ProjectedVolumeSourceDefaultMode)
|
||||
obj.DefaultMode = &perm
|
||||
}
|
||||
}
|
||||
func SetDefaults_PersistentVolume(obj *v1.PersistentVolume) {
|
||||
if obj.Status.Phase == "" {
|
||||
obj.Status.Phase = v1.VolumePending
|
||||
}
|
||||
if obj.Spec.PersistentVolumeReclaimPolicy == "" {
|
||||
obj.Spec.PersistentVolumeReclaimPolicy = v1.PersistentVolumeReclaimRetain
|
||||
}
|
||||
}
|
||||
func SetDefaults_PersistentVolumeClaim(obj *v1.PersistentVolumeClaim) {
|
||||
if obj.Status.Phase == "" {
|
||||
obj.Status.Phase = v1.ClaimPending
|
||||
}
|
||||
}
|
||||
func SetDefaults_ISCSIVolumeSource(obj *v1.ISCSIVolumeSource) {
|
||||
if obj.ISCSIInterface == "" {
|
||||
obj.ISCSIInterface = "default"
|
||||
}
|
||||
}
|
||||
func SetDefaults_AzureDiskVolumeSource(obj *v1.AzureDiskVolumeSource) {
|
||||
if obj.CachingMode == nil {
|
||||
obj.CachingMode = new(v1.AzureDataDiskCachingMode)
|
||||
*obj.CachingMode = v1.AzureDataDiskCachingReadWrite
|
||||
}
|
||||
if obj.Kind == nil {
|
||||
obj.Kind = new(v1.AzureDataDiskKind)
|
||||
*obj.Kind = v1.AzureSharedBlobDisk
|
||||
}
|
||||
if obj.FSType == nil {
|
||||
obj.FSType = new(string)
|
||||
*obj.FSType = "ext4"
|
||||
}
|
||||
if obj.ReadOnly == nil {
|
||||
obj.ReadOnly = new(bool)
|
||||
*obj.ReadOnly = false
|
||||
}
|
||||
}
|
||||
func SetDefaults_Endpoints(obj *v1.Endpoints) {
|
||||
for i := range obj.Subsets {
|
||||
ss := &obj.Subsets[i]
|
||||
for i := range ss.Ports {
|
||||
ep := &ss.Ports[i]
|
||||
if ep.Protocol == "" {
|
||||
ep.Protocol = v1.ProtocolTCP
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
func SetDefaults_HTTPGetAction(obj *v1.HTTPGetAction) {
|
||||
if obj.Path == "" {
|
||||
obj.Path = "/"
|
||||
}
|
||||
if obj.Scheme == "" {
|
||||
obj.Scheme = v1.URISchemeHTTP
|
||||
}
|
||||
}
|
||||
func SetDefaults_NamespaceStatus(obj *v1.NamespaceStatus) {
|
||||
if obj.Phase == "" {
|
||||
obj.Phase = v1.NamespaceActive
|
||||
}
|
||||
}
|
||||
func SetDefaults_Node(obj *v1.Node) {
|
||||
if obj.Spec.ExternalID == "" {
|
||||
obj.Spec.ExternalID = obj.Name
|
||||
}
|
||||
}
|
||||
func SetDefaults_NodeStatus(obj *v1.NodeStatus) {
|
||||
if obj.Allocatable == nil && obj.Capacity != nil {
|
||||
obj.Allocatable = make(v1.ResourceList, len(obj.Capacity))
|
||||
for key, value := range obj.Capacity {
|
||||
obj.Allocatable[key] = *(value.Copy())
|
||||
}
|
||||
obj.Allocatable = obj.Capacity
|
||||
}
|
||||
}
|
||||
func SetDefaults_ObjectFieldSelector(obj *v1.ObjectFieldSelector) {
|
||||
if obj.APIVersion == "" {
|
||||
obj.APIVersion = "v1"
|
||||
}
|
||||
}
|
||||
func SetDefaults_LimitRangeItem(obj *v1.LimitRangeItem) {
|
||||
// for container limits, we apply default values
|
||||
if obj.Type == v1.LimitTypeContainer {
|
||||
|
||||
if obj.Default == nil {
|
||||
obj.Default = make(v1.ResourceList)
|
||||
}
|
||||
if obj.DefaultRequest == nil {
|
||||
obj.DefaultRequest = make(v1.ResourceList)
|
||||
}
|
||||
|
||||
// If a default limit is unspecified, but the max is specified, default the limit to the max
|
||||
for key, value := range obj.Max {
|
||||
if _, exists := obj.Default[key]; !exists {
|
||||
obj.Default[key] = *(value.Copy())
|
||||
}
|
||||
}
|
||||
// If a default limit is specified, but the default request is not, default request to limit
|
||||
for key, value := range obj.Default {
|
||||
if _, exists := obj.DefaultRequest[key]; !exists {
|
||||
obj.DefaultRequest[key] = *(value.Copy())
|
||||
}
|
||||
}
|
||||
// If a default request is not specified, but the min is provided, default request to the min
|
||||
for key, value := range obj.Min {
|
||||
if _, exists := obj.DefaultRequest[key]; !exists {
|
||||
obj.DefaultRequest[key] = *(value.Copy())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
func SetDefaults_ConfigMap(obj *v1.ConfigMap) {
|
||||
if obj.Data == nil {
|
||||
obj.Data = make(map[string]string)
|
||||
}
|
||||
}
|
||||
|
||||
// With host networking default all container ports to host ports.
|
||||
func defaultHostNetworkPorts(containers *[]v1.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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func SetDefaults_RBDVolumeSource(obj *v1.RBDVolumeSource) {
|
||||
if obj.RBDPool == "" {
|
||||
obj.RBDPool = "rbd"
|
||||
}
|
||||
if obj.RadosUser == "" {
|
||||
obj.RadosUser = "admin"
|
||||
}
|
||||
if obj.Keyring == "" {
|
||||
obj.Keyring = "/etc/ceph/keyring"
|
||||
}
|
||||
}
|
||||
|
||||
func SetDefaults_ScaleIOVolumeSource(obj *v1.ScaleIOVolumeSource) {
|
||||
if obj.ProtectionDomain == "" {
|
||||
obj.ProtectionDomain = "default"
|
||||
}
|
||||
if obj.StoragePool == "" {
|
||||
obj.StoragePool = "default"
|
||||
}
|
||||
if obj.StorageMode == "" {
|
||||
obj.StorageMode = "ThinProvisioned"
|
||||
}
|
||||
if obj.FSType == "" {
|
||||
obj.FSType = "xfs"
|
||||
}
|
||||
}
|
||||
|
||||
func SetDefaults_HostPathVolumeSource(obj *v1.HostPathVolumeSource) {
|
||||
typeVol := v1.HostPathUnset
|
||||
if obj.Type == nil {
|
||||
obj.Type = &typeVol
|
||||
}
|
||||
}
|
||||
1334
vendor/k8s.io/kubernetes/pkg/api/v1/defaults_test.go
generated
vendored
1334
vendor/k8s.io/kubernetes/pkg/api/v1/defaults_test.go
generated
vendored
File diff suppressed because it is too large
Load diff
23
vendor/k8s.io/kubernetes/pkg/api/v1/doc.go
generated
vendored
23
vendor/k8s.io/kubernetes/pkg/api/v1/doc.go
generated
vendored
|
|
@ -1,23 +0,0 @@
|
|||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
// +k8s:conversion-gen=k8s.io/kubernetes/pkg/api
|
||||
// +k8s:conversion-gen-external-types=../../../vendor/k8s.io/api/core/v1
|
||||
// +k8s:defaulter-gen=TypeMeta
|
||||
// +k8s:defaulter-gen-input=../../../vendor/k8s.io/api/core/v1
|
||||
|
||||
// Package v1 is the v1 version of the API.
|
||||
package v1 // import "k8s.io/kubernetes/pkg/api/v1"
|
||||
65
vendor/k8s.io/kubernetes/pkg/api/v1/generate.go
generated
vendored
65
vendor/k8s.io/kubernetes/pkg/api/v1/generate.go
generated
vendored
|
|
@ -1,65 +0,0 @@
|
|||
/*
|
||||
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))
|
||||
}
|
||||
48
vendor/k8s.io/kubernetes/pkg/api/v1/helper/BUILD
generated
vendored
48
vendor/k8s.io/kubernetes/pkg/api/v1/helper/BUILD
generated
vendored
|
|
@ -1,48 +0,0 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
"go_test",
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["helpers_test.go"],
|
||||
library = ":go_default_library",
|
||||
deps = [
|
||||
"//vendor/k8s.io/api/core/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/equality:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/labels:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["helpers.go"],
|
||||
deps = [
|
||||
"//pkg/api/helper:go_default_library",
|
||||
"//vendor/k8s.io/api/core/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/resource:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/labels:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/selection:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [
|
||||
":package-srcs",
|
||||
"//pkg/api/v1/helper/qos:all-srcs",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
472
vendor/k8s.io/kubernetes/pkg/api/v1/helper/helpers.go
generated
vendored
472
vendor/k8s.io/kubernetes/pkg/api/v1/helper/helpers.go
generated
vendored
|
|
@ -1,472 +0,0 @@
|
|||
/*
|
||||
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 helper
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/apimachinery/pkg/selection"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
"k8s.io/kubernetes/pkg/api/helper"
|
||||
)
|
||||
|
||||
// IsExtendedResourceName returns true if the resource name is not in the
|
||||
// default namespace, or it has the opaque integer resource prefix.
|
||||
func IsExtendedResourceName(name v1.ResourceName) bool {
|
||||
// TODO: Remove OIR part following deprecation.
|
||||
return !IsDefaultNamespaceResource(name) || IsOpaqueIntResourceName(name)
|
||||
}
|
||||
|
||||
// IsDefaultNamespaceResource returns true if the resource name is in the
|
||||
// *kubernetes.io/ namespace. Partially-qualified (unprefixed) names are
|
||||
// implicitly in the kubernetes.io/ namespace.
|
||||
func IsDefaultNamespaceResource(name v1.ResourceName) bool {
|
||||
return !strings.Contains(string(name), "/") ||
|
||||
strings.Contains(string(name), v1.ResourceDefaultNamespacePrefix)
|
||||
|
||||
}
|
||||
|
||||
// IsHugePageResourceName returns true if the resource name has the huge page
|
||||
// resource prefix.
|
||||
func IsHugePageResourceName(name v1.ResourceName) bool {
|
||||
return strings.HasPrefix(string(name), v1.ResourceHugePagesPrefix)
|
||||
}
|
||||
|
||||
// HugePageResourceName returns a ResourceName with the canonical hugepage
|
||||
// prefix prepended for the specified page size. The page size is converted
|
||||
// to its canonical representation.
|
||||
func HugePageResourceName(pageSize resource.Quantity) v1.ResourceName {
|
||||
return v1.ResourceName(fmt.Sprintf("%s%s", v1.ResourceHugePagesPrefix, pageSize.String()))
|
||||
}
|
||||
|
||||
// HugePageSizeFromResourceName returns the page size for the specified huge page
|
||||
// resource name. If the specified input is not a valid huge page resource name
|
||||
// an error is returned.
|
||||
func HugePageSizeFromResourceName(name v1.ResourceName) (resource.Quantity, error) {
|
||||
if !IsHugePageResourceName(name) {
|
||||
return resource.Quantity{}, fmt.Errorf("resource name: %s is not valid hugepage name", name)
|
||||
}
|
||||
pageSize := strings.TrimPrefix(string(name), v1.ResourceHugePagesPrefix)
|
||||
return resource.ParseQuantity(pageSize)
|
||||
}
|
||||
|
||||
// IsOpaqueIntResourceName returns true if the resource name has the opaque
|
||||
// integer resource prefix.
|
||||
func IsOpaqueIntResourceName(name v1.ResourceName) bool {
|
||||
return strings.HasPrefix(string(name), v1.ResourceOpaqueIntPrefix)
|
||||
}
|
||||
|
||||
// OpaqueIntResourceName returns a ResourceName with the canonical opaque
|
||||
// integer prefix prepended. If the argument already has the prefix, it is
|
||||
// returned unmodified.
|
||||
func OpaqueIntResourceName(name string) v1.ResourceName {
|
||||
if IsOpaqueIntResourceName(v1.ResourceName(name)) {
|
||||
return v1.ResourceName(name)
|
||||
}
|
||||
return v1.ResourceName(fmt.Sprintf("%s%s", v1.ResourceOpaqueIntPrefix, name))
|
||||
}
|
||||
|
||||
var overcommitBlacklist = sets.NewString(string(v1.ResourceNvidiaGPU))
|
||||
|
||||
// IsOvercommitAllowed returns true if the resource is in the default
|
||||
// namespace and not blacklisted.
|
||||
func IsOvercommitAllowed(name v1.ResourceName) bool {
|
||||
return IsDefaultNamespaceResource(name) &&
|
||||
!overcommitBlacklist.Has(string(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 {
|
||||
return service.Spec.ClusterIP != v1.ClusterIPNone && service.Spec.ClusterIP != ""
|
||||
}
|
||||
|
||||
// this function aims to check if the service's cluster IP is requested or not
|
||||
func IsServiceIPRequested(service *v1.Service) bool {
|
||||
// ExternalName services are CNAME aliases to external ones. Ignore the IP.
|
||||
if service.Spec.Type == v1.ServiceTypeExternalName {
|
||||
return false
|
||||
}
|
||||
return service.Spec.ClusterIP == ""
|
||||
}
|
||||
|
||||
// AddToNodeAddresses appends the NodeAddresses to the passed-by-pointer slice,
|
||||
// only if they do not already exist
|
||||
func AddToNodeAddresses(addresses *[]v1.NodeAddress, addAddresses ...v1.NodeAddress) {
|
||||
for _, add := range addAddresses {
|
||||
exists := false
|
||||
for _, existing := range *addresses {
|
||||
if existing.Address == add.Address && existing.Type == add.Type {
|
||||
exists = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !exists {
|
||||
*addresses = append(*addresses, add)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: make method on LoadBalancerStatus?
|
||||
func LoadBalancerStatusEqual(l, r *v1.LoadBalancerStatus) bool {
|
||||
return ingressSliceEqual(l.Ingress, r.Ingress)
|
||||
}
|
||||
|
||||
func ingressSliceEqual(lhs, rhs []v1.LoadBalancerIngress) bool {
|
||||
if len(lhs) != len(rhs) {
|
||||
return false
|
||||
}
|
||||
for i := range lhs {
|
||||
if !ingressEqual(&lhs[i], &rhs[i]) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func ingressEqual(lhs, rhs *v1.LoadBalancerIngress) bool {
|
||||
if lhs.IP != rhs.IP {
|
||||
return false
|
||||
}
|
||||
if lhs.Hostname != rhs.Hostname {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// TODO: make method on LoadBalancerStatus?
|
||||
func LoadBalancerStatusDeepCopy(lb *v1.LoadBalancerStatus) *v1.LoadBalancerStatus {
|
||||
c := &v1.LoadBalancerStatus{}
|
||||
c.Ingress = make([]v1.LoadBalancerIngress, len(lb.Ingress))
|
||||
for i := range lb.Ingress {
|
||||
c.Ingress[i] = lb.Ingress[i]
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
// GetAccessModesAsString returns a string representation of an array of access modes.
|
||||
// modes, when present, are always in the same order: RWO,ROX,RWX.
|
||||
func GetAccessModesAsString(modes []v1.PersistentVolumeAccessMode) string {
|
||||
modes = removeDuplicateAccessModes(modes)
|
||||
modesStr := []string{}
|
||||
if containsAccessMode(modes, v1.ReadWriteOnce) {
|
||||
modesStr = append(modesStr, "RWO")
|
||||
}
|
||||
if containsAccessMode(modes, v1.ReadOnlyMany) {
|
||||
modesStr = append(modesStr, "ROX")
|
||||
}
|
||||
if containsAccessMode(modes, v1.ReadWriteMany) {
|
||||
modesStr = append(modesStr, "RWX")
|
||||
}
|
||||
return strings.Join(modesStr, ",")
|
||||
}
|
||||
|
||||
// GetAccessModesAsString returns an array of AccessModes from a string created by GetAccessModesAsString
|
||||
func GetAccessModesFromString(modes string) []v1.PersistentVolumeAccessMode {
|
||||
strmodes := strings.Split(modes, ",")
|
||||
accessModes := []v1.PersistentVolumeAccessMode{}
|
||||
for _, s := range strmodes {
|
||||
s = strings.Trim(s, " ")
|
||||
switch {
|
||||
case s == "RWO":
|
||||
accessModes = append(accessModes, v1.ReadWriteOnce)
|
||||
case s == "ROX":
|
||||
accessModes = append(accessModes, v1.ReadOnlyMany)
|
||||
case s == "RWX":
|
||||
accessModes = append(accessModes, v1.ReadWriteMany)
|
||||
}
|
||||
}
|
||||
return accessModes
|
||||
}
|
||||
|
||||
// removeDuplicateAccessModes returns an array of access modes without any duplicates
|
||||
func removeDuplicateAccessModes(modes []v1.PersistentVolumeAccessMode) []v1.PersistentVolumeAccessMode {
|
||||
accessModes := []v1.PersistentVolumeAccessMode{}
|
||||
for _, m := range modes {
|
||||
if !containsAccessMode(accessModes, m) {
|
||||
accessModes = append(accessModes, m)
|
||||
}
|
||||
}
|
||||
return accessModes
|
||||
}
|
||||
|
||||
func containsAccessMode(modes []v1.PersistentVolumeAccessMode, mode v1.PersistentVolumeAccessMode) bool {
|
||||
for _, m := range modes {
|
||||
if m == mode {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// NodeSelectorRequirementsAsSelector converts the []NodeSelectorRequirement api type into a struct that implements
|
||||
// labels.Selector.
|
||||
func NodeSelectorRequirementsAsSelector(nsm []v1.NodeSelectorRequirement) (labels.Selector, error) {
|
||||
if len(nsm) == 0 {
|
||||
return labels.Nothing(), nil
|
||||
}
|
||||
selector := labels.NewSelector()
|
||||
for _, expr := range nsm {
|
||||
var op selection.Operator
|
||||
switch expr.Operator {
|
||||
case v1.NodeSelectorOpIn:
|
||||
op = selection.In
|
||||
case v1.NodeSelectorOpNotIn:
|
||||
op = selection.NotIn
|
||||
case v1.NodeSelectorOpExists:
|
||||
op = selection.Exists
|
||||
case v1.NodeSelectorOpDoesNotExist:
|
||||
op = selection.DoesNotExist
|
||||
case v1.NodeSelectorOpGt:
|
||||
op = selection.GreaterThan
|
||||
case v1.NodeSelectorOpLt:
|
||||
op = selection.LessThan
|
||||
default:
|
||||
return nil, fmt.Errorf("%q is not a valid node selector operator", expr.Operator)
|
||||
}
|
||||
r, err := labels.NewRequirement(expr.Key, op, expr.Values)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
selector = selector.Add(*r)
|
||||
}
|
||||
return selector, nil
|
||||
}
|
||||
|
||||
// AddOrUpdateTolerationInPodSpec tries to add a toleration to the toleration list in PodSpec.
|
||||
// Returns true if something was updated, false otherwise.
|
||||
func AddOrUpdateTolerationInPodSpec(spec *v1.PodSpec, toleration *v1.Toleration) bool {
|
||||
podTolerations := spec.Tolerations
|
||||
|
||||
var newTolerations []v1.Toleration
|
||||
updated := false
|
||||
for i := range podTolerations {
|
||||
if toleration.MatchToleration(&podTolerations[i]) {
|
||||
if helper.Semantic.DeepEqual(toleration, podTolerations[i]) {
|
||||
return false
|
||||
}
|
||||
newTolerations = append(newTolerations, *toleration)
|
||||
updated = true
|
||||
continue
|
||||
}
|
||||
|
||||
newTolerations = append(newTolerations, podTolerations[i])
|
||||
}
|
||||
|
||||
if !updated {
|
||||
newTolerations = append(newTolerations, *toleration)
|
||||
}
|
||||
|
||||
spec.Tolerations = newTolerations
|
||||
return true
|
||||
}
|
||||
|
||||
// AddOrUpdateTolerationInPod tries to add a toleration to the pod's toleration list.
|
||||
// Returns true if something was updated, false otherwise.
|
||||
func AddOrUpdateTolerationInPod(pod *v1.Pod, toleration *v1.Toleration) bool {
|
||||
return AddOrUpdateTolerationInPodSpec(&pod.Spec, toleration)
|
||||
}
|
||||
|
||||
// TolerationsTolerateTaint checks if taint is tolerated by any of the tolerations.
|
||||
func TolerationsTolerateTaint(tolerations []v1.Toleration, taint *v1.Taint) bool {
|
||||
for i := range tolerations {
|
||||
if tolerations[i].ToleratesTaint(taint) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
type taintsFilterFunc func(*v1.Taint) bool
|
||||
|
||||
// TolerationsTolerateTaintsWithFilter checks if given tolerations tolerates
|
||||
// all the taints that apply to the filter in given taint list.
|
||||
func TolerationsTolerateTaintsWithFilter(tolerations []v1.Toleration, taints []v1.Taint, applyFilter taintsFilterFunc) bool {
|
||||
if len(taints) == 0 {
|
||||
return true
|
||||
}
|
||||
|
||||
for i := range taints {
|
||||
if applyFilter != nil && !applyFilter(&taints[i]) {
|
||||
continue
|
||||
}
|
||||
|
||||
if !TolerationsTolerateTaint(tolerations, &taints[i]) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// Returns true and list of Tolerations matching all Taints if all are tolerated, or false otherwise.
|
||||
func GetMatchingTolerations(taints []v1.Taint, tolerations []v1.Toleration) (bool, []v1.Toleration) {
|
||||
if len(taints) == 0 {
|
||||
return true, []v1.Toleration{}
|
||||
}
|
||||
if len(tolerations) == 0 && len(taints) > 0 {
|
||||
return false, []v1.Toleration{}
|
||||
}
|
||||
result := []v1.Toleration{}
|
||||
for i := range taints {
|
||||
tolerated := false
|
||||
for j := range tolerations {
|
||||
if tolerations[j].ToleratesTaint(&taints[i]) {
|
||||
result = append(result, tolerations[j])
|
||||
tolerated = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !tolerated {
|
||||
return false, []v1.Toleration{}
|
||||
}
|
||||
}
|
||||
return true, result
|
||||
}
|
||||
|
||||
func GetAvoidPodsFromNodeAnnotations(annotations map[string]string) (v1.AvoidPods, error) {
|
||||
var avoidPods v1.AvoidPods
|
||||
if len(annotations) > 0 && annotations[v1.PreferAvoidPodsAnnotationKey] != "" {
|
||||
err := json.Unmarshal([]byte(annotations[v1.PreferAvoidPodsAnnotationKey]), &avoidPods)
|
||||
if err != nil {
|
||||
return avoidPods, err
|
||||
}
|
||||
}
|
||||
return avoidPods, nil
|
||||
}
|
||||
|
||||
// SysctlsFromPodAnnotations parses the sysctl annotations into a slice of safe Sysctls
|
||||
// and a slice of unsafe Sysctls. This is only a convenience wrapper around
|
||||
// SysctlsFromPodAnnotation.
|
||||
func SysctlsFromPodAnnotations(a map[string]string) ([]v1.Sysctl, []v1.Sysctl, error) {
|
||||
safe, err := SysctlsFromPodAnnotation(a[v1.SysctlsPodAnnotationKey])
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
unsafe, err := SysctlsFromPodAnnotation(a[v1.UnsafeSysctlsPodAnnotationKey])
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
return safe, unsafe, nil
|
||||
}
|
||||
|
||||
// SysctlsFromPodAnnotation parses an annotation value into a slice of Sysctls.
|
||||
func SysctlsFromPodAnnotation(annotation string) ([]v1.Sysctl, error) {
|
||||
if len(annotation) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
kvs := strings.Split(annotation, ",")
|
||||
sysctls := make([]v1.Sysctl, len(kvs))
|
||||
for i, kv := range kvs {
|
||||
cs := strings.Split(kv, "=")
|
||||
if len(cs) != 2 || len(cs[0]) == 0 {
|
||||
return nil, fmt.Errorf("sysctl %q not of the format sysctl_name=value", kv)
|
||||
}
|
||||
sysctls[i].Name = cs[0]
|
||||
sysctls[i].Value = cs[1]
|
||||
}
|
||||
return sysctls, nil
|
||||
}
|
||||
|
||||
// PodAnnotationsFromSysctls creates an annotation value for a slice of Sysctls.
|
||||
func PodAnnotationsFromSysctls(sysctls []v1.Sysctl) string {
|
||||
if len(sysctls) == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
kvs := make([]string, len(sysctls))
|
||||
for i := range sysctls {
|
||||
kvs[i] = fmt.Sprintf("%s=%s", sysctls[i].Name, sysctls[i].Value)
|
||||
}
|
||||
return strings.Join(kvs, ",")
|
||||
}
|
||||
|
||||
// GetPersistentVolumeClass returns StorageClassName.
|
||||
func GetPersistentVolumeClass(volume *v1.PersistentVolume) string {
|
||||
// Use beta annotation first
|
||||
if class, found := volume.Annotations[v1.BetaStorageClassAnnotation]; found {
|
||||
return class
|
||||
}
|
||||
|
||||
return volume.Spec.StorageClassName
|
||||
}
|
||||
|
||||
// GetPersistentVolumeClaimClass returns StorageClassName. If no storage class was
|
||||
// requested, it returns "".
|
||||
func GetPersistentVolumeClaimClass(claim *v1.PersistentVolumeClaim) string {
|
||||
// Use beta annotation first
|
||||
if class, found := claim.Annotations[v1.BetaStorageClassAnnotation]; found {
|
||||
return class
|
||||
}
|
||||
|
||||
if claim.Spec.StorageClassName != nil {
|
||||
return *claim.Spec.StorageClassName
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
// PersistentVolumeClaimHasClass returns true if given claim has set StorageClassName field.
|
||||
func PersistentVolumeClaimHasClass(claim *v1.PersistentVolumeClaim) bool {
|
||||
// Use beta annotation first
|
||||
if _, found := claim.Annotations[v1.BetaStorageClassAnnotation]; found {
|
||||
return true
|
||||
}
|
||||
|
||||
if claim.Spec.StorageClassName != nil {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// GetStorageNodeAffinityFromAnnotation gets the json serialized data from PersistentVolume.Annotations
|
||||
// and converts it to the NodeAffinity type in api.
|
||||
// TODO: update when storage node affinity graduates to beta
|
||||
func GetStorageNodeAffinityFromAnnotation(annotations map[string]string) (*v1.NodeAffinity, error) {
|
||||
if len(annotations) > 0 && annotations[v1.AlphaStorageNodeAffinityAnnotation] != "" {
|
||||
var affinity v1.NodeAffinity
|
||||
err := json.Unmarshal([]byte(annotations[v1.AlphaStorageNodeAffinityAnnotation]), &affinity)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &affinity, nil
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// Converts NodeAffinity type to Alpha annotation for use in PersistentVolumes
|
||||
// TODO: update when storage node affinity graduates to beta
|
||||
func StorageNodeAffinityToAlphaAnnotation(annotations map[string]string, affinity *v1.NodeAffinity) error {
|
||||
if affinity == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
json, err := json.Marshal(*affinity)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
annotations[v1.AlphaStorageNodeAffinityAnnotation] = string(json)
|
||||
return nil
|
||||
}
|
||||
590
vendor/k8s.io/kubernetes/pkg/api/v1/helper/helpers_test.go
generated
vendored
590
vendor/k8s.io/kubernetes/pkg/api/v1/helper/helpers_test.go
generated
vendored
|
|
@ -1,590 +0,0 @@
|
|||
/*
|
||||
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 helper
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
apiequality "k8s.io/apimachinery/pkg/api/equality"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
)
|
||||
|
||||
func TestIsOpaqueIntResourceName(t *testing.T) { // resourceName input with the correct OpaqueIntResourceName prefix ("pod.alpha.kubernetes.io/opaque-int-resource-") should pass
|
||||
testCases := []struct {
|
||||
resourceName v1.ResourceName
|
||||
expectVal bool
|
||||
}{
|
||||
{
|
||||
resourceName: "pod.alpha.kubernetes.io/opaque-int-resource-foo",
|
||||
expectVal: true, // resourceName should pass because the resourceName has the correct prefix.
|
||||
},
|
||||
{
|
||||
resourceName: "foo",
|
||||
expectVal: false, // resourceName should fail because the resourceName has the wrong prefix.
|
||||
},
|
||||
{
|
||||
resourceName: "",
|
||||
expectVal: false, // resourceName should fail, empty resourceName.
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
tc := tc
|
||||
t.Run(fmt.Sprintf("resourceName input=%s, expected value=%v", tc.resourceName, tc.expectVal), func(t *testing.T) {
|
||||
t.Parallel()
|
||||
v := IsOpaqueIntResourceName(tc.resourceName)
|
||||
if v != tc.expectVal {
|
||||
t.Errorf("Got %v but expected %v", v, tc.expectVal)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestOpaqueIntResourceName(t *testing.T) { // each output should have the correct appended prefix ("pod.alpha.kubernetes.io/opaque-int-resource-") for opaque counted resources.
|
||||
testCases := []struct {
|
||||
name string
|
||||
expectVal v1.ResourceName
|
||||
}{
|
||||
{
|
||||
name: "foo",
|
||||
expectVal: "pod.alpha.kubernetes.io/opaque-int-resource-foo", // append prefix to input string foo
|
||||
},
|
||||
{
|
||||
name: "",
|
||||
expectVal: "pod.alpha.kubernetes.io/opaque-int-resource-", // append prefix to input empty string
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
tc := tc
|
||||
t.Run(fmt.Sprintf("name input=%s, expected value=%s", tc.name, tc.expectVal), func(t *testing.T) {
|
||||
t.Parallel()
|
||||
v := OpaqueIntResourceName(tc.name)
|
||||
if v != tc.expectVal {
|
||||
t.Errorf("Got %v but expected %v", v, tc.expectVal)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestAddToNodeAddresses(t *testing.T) {
|
||||
testCases := []struct {
|
||||
existing []v1.NodeAddress
|
||||
toAdd []v1.NodeAddress
|
||||
expected []v1.NodeAddress
|
||||
}{
|
||||
{
|
||||
existing: []v1.NodeAddress{},
|
||||
toAdd: []v1.NodeAddress{},
|
||||
expected: []v1.NodeAddress{},
|
||||
},
|
||||
{
|
||||
existing: []v1.NodeAddress{},
|
||||
toAdd: []v1.NodeAddress{
|
||||
{Type: v1.NodeExternalIP, Address: "1.1.1.1"},
|
||||
{Type: v1.NodeHostName, Address: "localhost"},
|
||||
},
|
||||
expected: []v1.NodeAddress{
|
||||
{Type: v1.NodeExternalIP, Address: "1.1.1.1"},
|
||||
{Type: v1.NodeHostName, Address: "localhost"},
|
||||
},
|
||||
},
|
||||
{
|
||||
existing: []v1.NodeAddress{},
|
||||
toAdd: []v1.NodeAddress{
|
||||
{Type: v1.NodeExternalIP, Address: "1.1.1.1"},
|
||||
{Type: v1.NodeExternalIP, Address: "1.1.1.1"},
|
||||
},
|
||||
expected: []v1.NodeAddress{
|
||||
{Type: v1.NodeExternalIP, Address: "1.1.1.1"},
|
||||
},
|
||||
},
|
||||
{
|
||||
existing: []v1.NodeAddress{
|
||||
{Type: v1.NodeExternalIP, Address: "1.1.1.1"},
|
||||
{Type: v1.NodeInternalIP, Address: "10.1.1.1"},
|
||||
},
|
||||
toAdd: []v1.NodeAddress{
|
||||
{Type: v1.NodeExternalIP, Address: "1.1.1.1"},
|
||||
{Type: v1.NodeHostName, Address: "localhost"},
|
||||
},
|
||||
expected: []v1.NodeAddress{
|
||||
{Type: v1.NodeExternalIP, Address: "1.1.1.1"},
|
||||
{Type: v1.NodeInternalIP, Address: "10.1.1.1"},
|
||||
{Type: v1.NodeHostName, Address: "localhost"},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for i, tc := range testCases {
|
||||
AddToNodeAddresses(&tc.existing, tc.toAdd...)
|
||||
if !apiequality.Semantic.DeepEqual(tc.expected, tc.existing) {
|
||||
t.Errorf("case[%d], expected: %v, got: %v", i, tc.expected, tc.existing)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetAccessModesFromString(t *testing.T) {
|
||||
modes := GetAccessModesFromString("ROX")
|
||||
if !containsAccessMode(modes, v1.ReadOnlyMany) {
|
||||
t.Errorf("Expected mode %s, but got %+v", v1.ReadOnlyMany, modes)
|
||||
}
|
||||
|
||||
modes = GetAccessModesFromString("ROX,RWX")
|
||||
if !containsAccessMode(modes, v1.ReadOnlyMany) {
|
||||
t.Errorf("Expected mode %s, but got %+v", v1.ReadOnlyMany, modes)
|
||||
}
|
||||
if !containsAccessMode(modes, v1.ReadWriteMany) {
|
||||
t.Errorf("Expected mode %s, but got %+v", v1.ReadWriteMany, modes)
|
||||
}
|
||||
|
||||
modes = GetAccessModesFromString("RWO,ROX,RWX")
|
||||
if !containsAccessMode(modes, v1.ReadOnlyMany) {
|
||||
t.Errorf("Expected mode %s, but got %+v", v1.ReadOnlyMany, modes)
|
||||
}
|
||||
if !containsAccessMode(modes, v1.ReadWriteMany) {
|
||||
t.Errorf("Expected mode %s, but got %+v", v1.ReadWriteMany, modes)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRemoveDuplicateAccessModes(t *testing.T) {
|
||||
modes := []v1.PersistentVolumeAccessMode{
|
||||
v1.ReadWriteOnce, v1.ReadOnlyMany, v1.ReadOnlyMany, v1.ReadOnlyMany,
|
||||
}
|
||||
modes = removeDuplicateAccessModes(modes)
|
||||
if len(modes) != 2 {
|
||||
t.Errorf("Expected 2 distinct modes in set but found %v", len(modes))
|
||||
}
|
||||
}
|
||||
|
||||
func TestNodeSelectorRequirementsAsSelector(t *testing.T) {
|
||||
matchExpressions := []v1.NodeSelectorRequirement{{
|
||||
Key: "foo",
|
||||
Operator: v1.NodeSelectorOpIn,
|
||||
Values: []string{"bar", "baz"},
|
||||
}}
|
||||
mustParse := func(s string) labels.Selector {
|
||||
out, e := labels.Parse(s)
|
||||
if e != nil {
|
||||
panic(e)
|
||||
}
|
||||
return out
|
||||
}
|
||||
tc := []struct {
|
||||
in []v1.NodeSelectorRequirement
|
||||
out labels.Selector
|
||||
expectErr bool
|
||||
}{
|
||||
{in: nil, out: labels.Nothing()},
|
||||
{in: []v1.NodeSelectorRequirement{}, out: labels.Nothing()},
|
||||
{
|
||||
in: matchExpressions,
|
||||
out: mustParse("foo in (baz,bar)"),
|
||||
},
|
||||
{
|
||||
in: []v1.NodeSelectorRequirement{{
|
||||
Key: "foo",
|
||||
Operator: v1.NodeSelectorOpExists,
|
||||
Values: []string{"bar", "baz"},
|
||||
}},
|
||||
expectErr: true,
|
||||
},
|
||||
{
|
||||
in: []v1.NodeSelectorRequirement{{
|
||||
Key: "foo",
|
||||
Operator: v1.NodeSelectorOpGt,
|
||||
Values: []string{"1"},
|
||||
}},
|
||||
out: mustParse("foo>1"),
|
||||
},
|
||||
{
|
||||
in: []v1.NodeSelectorRequirement{{
|
||||
Key: "bar",
|
||||
Operator: v1.NodeSelectorOpLt,
|
||||
Values: []string{"7"},
|
||||
}},
|
||||
out: mustParse("bar<7"),
|
||||
},
|
||||
}
|
||||
|
||||
for i, tc := range tc {
|
||||
out, err := NodeSelectorRequirementsAsSelector(tc.in)
|
||||
if err == nil && tc.expectErr {
|
||||
t.Errorf("[%v]expected error but got none.", i)
|
||||
}
|
||||
if err != nil && !tc.expectErr {
|
||||
t.Errorf("[%v]did not expect error but got: %v", i, err)
|
||||
}
|
||||
if !reflect.DeepEqual(out, tc.out) {
|
||||
t.Errorf("[%v]expected:\n\t%+v\nbut got:\n\t%+v", i, tc.out, out)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestTolerationsTolerateTaintsWithFilter(t *testing.T) {
|
||||
testCases := []struct {
|
||||
description string
|
||||
tolerations []v1.Toleration
|
||||
taints []v1.Taint
|
||||
applyFilter taintsFilterFunc
|
||||
expectTolerated bool
|
||||
}{
|
||||
{
|
||||
description: "empty tolerations tolerate empty taints",
|
||||
tolerations: []v1.Toleration{},
|
||||
taints: []v1.Taint{},
|
||||
applyFilter: func(t *v1.Taint) bool { return true },
|
||||
expectTolerated: true,
|
||||
},
|
||||
{
|
||||
description: "non-empty tolerations tolerate empty taints",
|
||||
tolerations: []v1.Toleration{
|
||||
{
|
||||
Key: "foo",
|
||||
Operator: "Exists",
|
||||
Effect: v1.TaintEffectNoSchedule,
|
||||
},
|
||||
},
|
||||
taints: []v1.Taint{},
|
||||
applyFilter: func(t *v1.Taint) bool { return true },
|
||||
expectTolerated: true,
|
||||
},
|
||||
{
|
||||
description: "tolerations match all taints, expect tolerated",
|
||||
tolerations: []v1.Toleration{
|
||||
{
|
||||
Key: "foo",
|
||||
Operator: "Exists",
|
||||
Effect: v1.TaintEffectNoSchedule,
|
||||
},
|
||||
},
|
||||
taints: []v1.Taint{
|
||||
{
|
||||
Key: "foo",
|
||||
Effect: v1.TaintEffectNoSchedule,
|
||||
},
|
||||
},
|
||||
applyFilter: func(t *v1.Taint) bool { return true },
|
||||
expectTolerated: true,
|
||||
},
|
||||
{
|
||||
description: "tolerations don't match taints, but no taints apply to the filter, expect tolerated",
|
||||
tolerations: []v1.Toleration{
|
||||
{
|
||||
Key: "foo",
|
||||
Operator: "Exists",
|
||||
Effect: v1.TaintEffectNoSchedule,
|
||||
},
|
||||
},
|
||||
taints: []v1.Taint{
|
||||
{
|
||||
Key: "bar",
|
||||
Effect: v1.TaintEffectNoSchedule,
|
||||
},
|
||||
},
|
||||
applyFilter: func(t *v1.Taint) bool { return false },
|
||||
expectTolerated: true,
|
||||
},
|
||||
{
|
||||
description: "no filterFunc indicated, means all taints apply to the filter, tolerations don't match taints, expect untolerated",
|
||||
tolerations: []v1.Toleration{
|
||||
{
|
||||
Key: "foo",
|
||||
Operator: "Exists",
|
||||
Effect: v1.TaintEffectNoSchedule,
|
||||
},
|
||||
},
|
||||
taints: []v1.Taint{
|
||||
{
|
||||
Key: "bar",
|
||||
Effect: v1.TaintEffectNoSchedule,
|
||||
},
|
||||
},
|
||||
applyFilter: nil,
|
||||
expectTolerated: false,
|
||||
},
|
||||
{
|
||||
description: "tolerations match taints, expect tolerated",
|
||||
tolerations: []v1.Toleration{
|
||||
{
|
||||
Key: "foo",
|
||||
Operator: "Exists",
|
||||
Effect: v1.TaintEffectNoExecute,
|
||||
},
|
||||
},
|
||||
taints: []v1.Taint{
|
||||
{
|
||||
Key: "foo",
|
||||
Effect: v1.TaintEffectNoExecute,
|
||||
},
|
||||
{
|
||||
Key: "bar",
|
||||
Effect: v1.TaintEffectNoSchedule,
|
||||
},
|
||||
},
|
||||
applyFilter: func(t *v1.Taint) bool { return t.Effect == v1.TaintEffectNoExecute },
|
||||
expectTolerated: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
if tc.expectTolerated != TolerationsTolerateTaintsWithFilter(tc.tolerations, tc.taints, tc.applyFilter) {
|
||||
filteredTaints := []v1.Taint{}
|
||||
for _, taint := range tc.taints {
|
||||
if tc.applyFilter != nil && !tc.applyFilter(&taint) {
|
||||
continue
|
||||
}
|
||||
filteredTaints = append(filteredTaints, taint)
|
||||
}
|
||||
t.Errorf("[%s] expect tolerations %+v tolerate filtered taints %+v in taints %+v", tc.description, tc.tolerations, filteredTaints, tc.taints)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetAvoidPodsFromNode(t *testing.T) {
|
||||
controllerFlag := true
|
||||
testCases := []struct {
|
||||
node *v1.Node
|
||||
expectValue v1.AvoidPods
|
||||
expectErr bool
|
||||
}{
|
||||
{
|
||||
node: &v1.Node{},
|
||||
expectValue: v1.AvoidPods{},
|
||||
expectErr: false,
|
||||
},
|
||||
{
|
||||
node: &v1.Node{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Annotations: map[string]string{
|
||||
v1.PreferAvoidPodsAnnotationKey: `
|
||||
{
|
||||
"preferAvoidPods": [
|
||||
{
|
||||
"podSignature": {
|
||||
"podController": {
|
||||
"apiVersion": "v1",
|
||||
"kind": "ReplicationController",
|
||||
"name": "foo",
|
||||
"uid": "abcdef123456",
|
||||
"controller": true
|
||||
}
|
||||
},
|
||||
"reason": "some reason",
|
||||
"message": "some message"
|
||||
}
|
||||
]
|
||||
}`,
|
||||
},
|
||||
},
|
||||
},
|
||||
expectValue: v1.AvoidPods{
|
||||
PreferAvoidPods: []v1.PreferAvoidPodsEntry{
|
||||
{
|
||||
PodSignature: v1.PodSignature{
|
||||
PodController: &metav1.OwnerReference{
|
||||
APIVersion: "v1",
|
||||
Kind: "ReplicationController",
|
||||
Name: "foo",
|
||||
UID: "abcdef123456",
|
||||
Controller: &controllerFlag,
|
||||
},
|
||||
},
|
||||
Reason: "some reason",
|
||||
Message: "some message",
|
||||
},
|
||||
},
|
||||
},
|
||||
expectErr: false,
|
||||
},
|
||||
{
|
||||
node: &v1.Node{
|
||||
// Missing end symbol of "podController" and "podSignature"
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Annotations: map[string]string{
|
||||
v1.PreferAvoidPodsAnnotationKey: `
|
||||
{
|
||||
"preferAvoidPods": [
|
||||
{
|
||||
"podSignature": {
|
||||
"podController": {
|
||||
"kind": "ReplicationController",
|
||||
"apiVersion": "v1"
|
||||
"reason": "some reason",
|
||||
"message": "some message"
|
||||
}
|
||||
]
|
||||
}`,
|
||||
},
|
||||
},
|
||||
},
|
||||
expectValue: v1.AvoidPods{},
|
||||
expectErr: true,
|
||||
},
|
||||
}
|
||||
|
||||
for i, tc := range testCases {
|
||||
v, err := GetAvoidPodsFromNodeAnnotations(tc.node.Annotations)
|
||||
if err == nil && tc.expectErr {
|
||||
t.Errorf("[%v]expected error but got none.", i)
|
||||
}
|
||||
if err != nil && !tc.expectErr {
|
||||
t.Errorf("[%v]did not expect error but got: %v", i, err)
|
||||
}
|
||||
if !reflect.DeepEqual(tc.expectValue, v) {
|
||||
t.Errorf("[%v]expect value %v but got %v with %v", i, tc.expectValue, v, v.PreferAvoidPods[0].PodSignature.PodController.Controller)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSysctlsFromPodAnnotation(t *testing.T) {
|
||||
type Test struct {
|
||||
annotation string
|
||||
expectValue []v1.Sysctl
|
||||
expectErr bool
|
||||
}
|
||||
for i, test := range []Test{
|
||||
{
|
||||
annotation: "",
|
||||
expectValue: nil,
|
||||
},
|
||||
{
|
||||
annotation: "foo.bar",
|
||||
expectErr: true,
|
||||
},
|
||||
{
|
||||
annotation: "=123",
|
||||
expectErr: true,
|
||||
},
|
||||
{
|
||||
annotation: "foo.bar=",
|
||||
expectValue: []v1.Sysctl{{Name: "foo.bar", Value: ""}},
|
||||
},
|
||||
{
|
||||
annotation: "foo.bar=42",
|
||||
expectValue: []v1.Sysctl{{Name: "foo.bar", Value: "42"}},
|
||||
},
|
||||
{
|
||||
annotation: "foo.bar=42,",
|
||||
expectErr: true,
|
||||
},
|
||||
{
|
||||
annotation: "foo.bar=42,abc.def=1",
|
||||
expectValue: []v1.Sysctl{{Name: "foo.bar", Value: "42"}, {Name: "abc.def", Value: "1"}},
|
||||
},
|
||||
} {
|
||||
sysctls, err := SysctlsFromPodAnnotation(test.annotation)
|
||||
if test.expectErr && err == nil {
|
||||
t.Errorf("[%v]expected error but got none", i)
|
||||
} else if !test.expectErr && err != nil {
|
||||
t.Errorf("[%v]did not expect error but got: %v", i, err)
|
||||
} else if !reflect.DeepEqual(sysctls, test.expectValue) {
|
||||
t.Errorf("[%v]expect value %v but got %v", i, test.expectValue, sysctls)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: remove when alpha support for topology constraints is removed
|
||||
func TestGetNodeAffinityFromAnnotations(t *testing.T) {
|
||||
testCases := []struct {
|
||||
annotations map[string]string
|
||||
expectErr bool
|
||||
}{
|
||||
{
|
||||
annotations: nil,
|
||||
expectErr: false,
|
||||
},
|
||||
{
|
||||
annotations: map[string]string{},
|
||||
expectErr: false,
|
||||
},
|
||||
{
|
||||
annotations: map[string]string{
|
||||
v1.AlphaStorageNodeAffinityAnnotation: `{
|
||||
"requiredDuringSchedulingIgnoredDuringExecution": {
|
||||
"nodeSelectorTerms": [
|
||||
{ "matchExpressions": [
|
||||
{ "key": "test-key1",
|
||||
"operator": "In",
|
||||
"values": ["test-value1", "test-value2"]
|
||||
},
|
||||
{ "key": "test-key2",
|
||||
"operator": "In",
|
||||
"values": ["test-value1", "test-value2"]
|
||||
}
|
||||
]}
|
||||
]}
|
||||
}`,
|
||||
},
|
||||
expectErr: false,
|
||||
},
|
||||
{
|
||||
annotations: map[string]string{
|
||||
v1.AlphaStorageNodeAffinityAnnotation: `[{
|
||||
"requiredDuringSchedulingIgnoredDuringExecution": {
|
||||
"nodeSelectorTerms": [
|
||||
{ "matchExpressions": [
|
||||
{ "key": "test-key1",
|
||||
"operator": "In",
|
||||
"values": ["test-value1", "test-value2"]
|
||||
},
|
||||
{ "key": "test-key2",
|
||||
"operator": "In",
|
||||
"values": ["test-value1", "test-value2"]
|
||||
}
|
||||
]}
|
||||
]}
|
||||
}]`,
|
||||
},
|
||||
expectErr: true,
|
||||
},
|
||||
{
|
||||
annotations: map[string]string{
|
||||
v1.AlphaStorageNodeAffinityAnnotation: `{
|
||||
"requiredDuringSchedulingIgnoredDuringExecution": {
|
||||
"nodeSelectorTerms":
|
||||
"matchExpressions": [
|
||||
{ "key": "test-key1",
|
||||
"operator": "In",
|
||||
"values": ["test-value1", "test-value2"]
|
||||
},
|
||||
{ "key": "test-key2",
|
||||
"operator": "In",
|
||||
"values": ["test-value1", "test-value2"]
|
||||
}
|
||||
]}
|
||||
}
|
||||
}`,
|
||||
},
|
||||
expectErr: true,
|
||||
},
|
||||
}
|
||||
|
||||
for i, tc := range testCases {
|
||||
_, err := GetStorageNodeAffinityFromAnnotation(tc.annotations)
|
||||
if err == nil && tc.expectErr {
|
||||
t.Errorf("[%v]expected error but got none.", i)
|
||||
}
|
||||
if err != nil && !tc.expectErr {
|
||||
t.Errorf("[%v]did not expect error but got: %v", i, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
2
vendor/k8s.io/kubernetes/pkg/api/v1/pod/BUILD
generated
vendored
2
vendor/k8s.io/kubernetes/pkg/api/v1/pod/BUILD
generated
vendored
|
|
@ -9,6 +9,7 @@ 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",
|
||||
|
|
@ -19,6 +20,7 @@ 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",
|
||||
|
|
|
|||
46
vendor/k8s.io/kubernetes/pkg/api/v1/register.go
generated
vendored
46
vendor/k8s.io/kubernetes/pkg/api/v1/register.go
generated
vendored
|
|
@ -1,46 +0,0 @@
|
|||
/*
|
||||
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 v1
|
||||
|
||||
import (
|
||||
"k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
)
|
||||
|
||||
var (
|
||||
localSchemeBuilder = &v1.SchemeBuilder
|
||||
AddToScheme = localSchemeBuilder.AddToScheme
|
||||
)
|
||||
|
||||
func init() {
|
||||
// We only register manually written functions here. The registration of the
|
||||
// generated functions takes place in the generated files. The separation
|
||||
// makes the code compile even when the generated files are missing.
|
||||
localSchemeBuilder.Register(addDefaultingFuncs, addConversionFuncs, addFastPathConversionFuncs)
|
||||
}
|
||||
|
||||
// TODO: remove these global varialbes
|
||||
// GroupName is the group name use in this package
|
||||
const GroupName = ""
|
||||
|
||||
// SchemeGroupVersion is group version used to register these objects
|
||||
var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1"}
|
||||
|
||||
// Resource takes an unqualified resource and returns a Group qualified GroupResource
|
||||
func Resource(resource string) schema.GroupResource {
|
||||
return SchemeGroupVersion.WithResource(resource).GroupResource()
|
||||
}
|
||||
5354
vendor/k8s.io/kubernetes/pkg/api/v1/zz_generated.conversion.go
generated
vendored
5354
vendor/k8s.io/kubernetes/pkg/api/v1/zz_generated.conversion.go
generated
vendored
File diff suppressed because it is too large
Load diff
648
vendor/k8s.io/kubernetes/pkg/api/v1/zz_generated.defaults.go
generated
vendored
648
vendor/k8s.io/kubernetes/pkg/api/v1/zz_generated.defaults.go
generated
vendored
|
|
@ -1,648 +0,0 @@
|
|||
// +build !ignore_autogenerated
|
||||
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
// This file was autogenerated by defaulter-gen. Do not edit it manually!
|
||||
|
||||
package v1
|
||||
|
||||
import (
|
||||
v1 "k8s.io/api/core/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
// RegisterDefaults adds defaulters functions to the given scheme.
|
||||
// Public to allow building arbitrary schemes.
|
||||
// All generated defaulters are covering - they call all nested defaulters.
|
||||
func RegisterDefaults(scheme *runtime.Scheme) error {
|
||||
scheme.AddTypeDefaultingFunc(&v1.ConfigMap{}, func(obj interface{}) { SetObjectDefaults_ConfigMap(obj.(*v1.ConfigMap)) })
|
||||
scheme.AddTypeDefaultingFunc(&v1.ConfigMapList{}, func(obj interface{}) { SetObjectDefaults_ConfigMapList(obj.(*v1.ConfigMapList)) })
|
||||
scheme.AddTypeDefaultingFunc(&v1.Endpoints{}, func(obj interface{}) { SetObjectDefaults_Endpoints(obj.(*v1.Endpoints)) })
|
||||
scheme.AddTypeDefaultingFunc(&v1.EndpointsList{}, func(obj interface{}) { SetObjectDefaults_EndpointsList(obj.(*v1.EndpointsList)) })
|
||||
scheme.AddTypeDefaultingFunc(&v1.LimitRange{}, func(obj interface{}) { SetObjectDefaults_LimitRange(obj.(*v1.LimitRange)) })
|
||||
scheme.AddTypeDefaultingFunc(&v1.LimitRangeList{}, func(obj interface{}) { SetObjectDefaults_LimitRangeList(obj.(*v1.LimitRangeList)) })
|
||||
scheme.AddTypeDefaultingFunc(&v1.Namespace{}, func(obj interface{}) { SetObjectDefaults_Namespace(obj.(*v1.Namespace)) })
|
||||
scheme.AddTypeDefaultingFunc(&v1.NamespaceList{}, func(obj interface{}) { SetObjectDefaults_NamespaceList(obj.(*v1.NamespaceList)) })
|
||||
scheme.AddTypeDefaultingFunc(&v1.Node{}, func(obj interface{}) { SetObjectDefaults_Node(obj.(*v1.Node)) })
|
||||
scheme.AddTypeDefaultingFunc(&v1.NodeList{}, func(obj interface{}) { SetObjectDefaults_NodeList(obj.(*v1.NodeList)) })
|
||||
scheme.AddTypeDefaultingFunc(&v1.PersistentVolume{}, func(obj interface{}) { SetObjectDefaults_PersistentVolume(obj.(*v1.PersistentVolume)) })
|
||||
scheme.AddTypeDefaultingFunc(&v1.PersistentVolumeClaim{}, func(obj interface{}) { SetObjectDefaults_PersistentVolumeClaim(obj.(*v1.PersistentVolumeClaim)) })
|
||||
scheme.AddTypeDefaultingFunc(&v1.PersistentVolumeClaimList{}, func(obj interface{}) {
|
||||
SetObjectDefaults_PersistentVolumeClaimList(obj.(*v1.PersistentVolumeClaimList))
|
||||
})
|
||||
scheme.AddTypeDefaultingFunc(&v1.PersistentVolumeList{}, func(obj interface{}) { SetObjectDefaults_PersistentVolumeList(obj.(*v1.PersistentVolumeList)) })
|
||||
scheme.AddTypeDefaultingFunc(&v1.Pod{}, func(obj interface{}) { SetObjectDefaults_Pod(obj.(*v1.Pod)) })
|
||||
scheme.AddTypeDefaultingFunc(&v1.PodAttachOptions{}, func(obj interface{}) { SetObjectDefaults_PodAttachOptions(obj.(*v1.PodAttachOptions)) })
|
||||
scheme.AddTypeDefaultingFunc(&v1.PodExecOptions{}, func(obj interface{}) { SetObjectDefaults_PodExecOptions(obj.(*v1.PodExecOptions)) })
|
||||
scheme.AddTypeDefaultingFunc(&v1.PodList{}, func(obj interface{}) { SetObjectDefaults_PodList(obj.(*v1.PodList)) })
|
||||
scheme.AddTypeDefaultingFunc(&v1.PodTemplate{}, func(obj interface{}) { SetObjectDefaults_PodTemplate(obj.(*v1.PodTemplate)) })
|
||||
scheme.AddTypeDefaultingFunc(&v1.PodTemplateList{}, func(obj interface{}) { SetObjectDefaults_PodTemplateList(obj.(*v1.PodTemplateList)) })
|
||||
scheme.AddTypeDefaultingFunc(&v1.ReplicationController{}, func(obj interface{}) { SetObjectDefaults_ReplicationController(obj.(*v1.ReplicationController)) })
|
||||
scheme.AddTypeDefaultingFunc(&v1.ReplicationControllerList{}, func(obj interface{}) {
|
||||
SetObjectDefaults_ReplicationControllerList(obj.(*v1.ReplicationControllerList))
|
||||
})
|
||||
scheme.AddTypeDefaultingFunc(&v1.ResourceQuota{}, func(obj interface{}) { SetObjectDefaults_ResourceQuota(obj.(*v1.ResourceQuota)) })
|
||||
scheme.AddTypeDefaultingFunc(&v1.ResourceQuotaList{}, func(obj interface{}) { SetObjectDefaults_ResourceQuotaList(obj.(*v1.ResourceQuotaList)) })
|
||||
scheme.AddTypeDefaultingFunc(&v1.Secret{}, func(obj interface{}) { SetObjectDefaults_Secret(obj.(*v1.Secret)) })
|
||||
scheme.AddTypeDefaultingFunc(&v1.SecretList{}, func(obj interface{}) { SetObjectDefaults_SecretList(obj.(*v1.SecretList)) })
|
||||
scheme.AddTypeDefaultingFunc(&v1.Service{}, func(obj interface{}) { SetObjectDefaults_Service(obj.(*v1.Service)) })
|
||||
scheme.AddTypeDefaultingFunc(&v1.ServiceList{}, func(obj interface{}) { SetObjectDefaults_ServiceList(obj.(*v1.ServiceList)) })
|
||||
return nil
|
||||
}
|
||||
|
||||
func SetObjectDefaults_ConfigMap(in *v1.ConfigMap) {
|
||||
SetDefaults_ConfigMap(in)
|
||||
}
|
||||
|
||||
func SetObjectDefaults_ConfigMapList(in *v1.ConfigMapList) {
|
||||
for i := range in.Items {
|
||||
a := &in.Items[i]
|
||||
SetObjectDefaults_ConfigMap(a)
|
||||
}
|
||||
}
|
||||
|
||||
func SetObjectDefaults_Endpoints(in *v1.Endpoints) {
|
||||
SetDefaults_Endpoints(in)
|
||||
}
|
||||
|
||||
func SetObjectDefaults_EndpointsList(in *v1.EndpointsList) {
|
||||
for i := range in.Items {
|
||||
a := &in.Items[i]
|
||||
SetObjectDefaults_Endpoints(a)
|
||||
}
|
||||
}
|
||||
|
||||
func SetObjectDefaults_LimitRange(in *v1.LimitRange) {
|
||||
for i := range in.Spec.Limits {
|
||||
a := &in.Spec.Limits[i]
|
||||
SetDefaults_LimitRangeItem(a)
|
||||
SetDefaults_ResourceList(&a.Max)
|
||||
SetDefaults_ResourceList(&a.Min)
|
||||
SetDefaults_ResourceList(&a.Default)
|
||||
SetDefaults_ResourceList(&a.DefaultRequest)
|
||||
SetDefaults_ResourceList(&a.MaxLimitRequestRatio)
|
||||
}
|
||||
}
|
||||
|
||||
func SetObjectDefaults_LimitRangeList(in *v1.LimitRangeList) {
|
||||
for i := range in.Items {
|
||||
a := &in.Items[i]
|
||||
SetObjectDefaults_LimitRange(a)
|
||||
}
|
||||
}
|
||||
|
||||
func SetObjectDefaults_Namespace(in *v1.Namespace) {
|
||||
SetDefaults_NamespaceStatus(&in.Status)
|
||||
}
|
||||
|
||||
func SetObjectDefaults_NamespaceList(in *v1.NamespaceList) {
|
||||
for i := range in.Items {
|
||||
a := &in.Items[i]
|
||||
SetObjectDefaults_Namespace(a)
|
||||
}
|
||||
}
|
||||
|
||||
func SetObjectDefaults_Node(in *v1.Node) {
|
||||
SetDefaults_Node(in)
|
||||
SetDefaults_NodeStatus(&in.Status)
|
||||
SetDefaults_ResourceList(&in.Status.Capacity)
|
||||
SetDefaults_ResourceList(&in.Status.Allocatable)
|
||||
}
|
||||
|
||||
func SetObjectDefaults_NodeList(in *v1.NodeList) {
|
||||
for i := range in.Items {
|
||||
a := &in.Items[i]
|
||||
SetObjectDefaults_Node(a)
|
||||
}
|
||||
}
|
||||
|
||||
func SetObjectDefaults_PersistentVolume(in *v1.PersistentVolume) {
|
||||
SetDefaults_PersistentVolume(in)
|
||||
SetDefaults_ResourceList(&in.Spec.Capacity)
|
||||
if in.Spec.PersistentVolumeSource.HostPath != nil {
|
||||
SetDefaults_HostPathVolumeSource(in.Spec.PersistentVolumeSource.HostPath)
|
||||
}
|
||||
if in.Spec.PersistentVolumeSource.RBD != nil {
|
||||
SetDefaults_RBDVolumeSource(in.Spec.PersistentVolumeSource.RBD)
|
||||
}
|
||||
if in.Spec.PersistentVolumeSource.ISCSI != nil {
|
||||
SetDefaults_ISCSIVolumeSource(in.Spec.PersistentVolumeSource.ISCSI)
|
||||
}
|
||||
if in.Spec.PersistentVolumeSource.AzureDisk != nil {
|
||||
SetDefaults_AzureDiskVolumeSource(in.Spec.PersistentVolumeSource.AzureDisk)
|
||||
}
|
||||
if in.Spec.PersistentVolumeSource.ScaleIO != nil {
|
||||
SetDefaults_ScaleIOVolumeSource(in.Spec.PersistentVolumeSource.ScaleIO)
|
||||
}
|
||||
}
|
||||
|
||||
func SetObjectDefaults_PersistentVolumeClaim(in *v1.PersistentVolumeClaim) {
|
||||
SetDefaults_PersistentVolumeClaim(in)
|
||||
SetDefaults_ResourceList(&in.Spec.Resources.Limits)
|
||||
SetDefaults_ResourceList(&in.Spec.Resources.Requests)
|
||||
SetDefaults_ResourceList(&in.Status.Capacity)
|
||||
}
|
||||
|
||||
func SetObjectDefaults_PersistentVolumeClaimList(in *v1.PersistentVolumeClaimList) {
|
||||
for i := range in.Items {
|
||||
a := &in.Items[i]
|
||||
SetObjectDefaults_PersistentVolumeClaim(a)
|
||||
}
|
||||
}
|
||||
|
||||
func SetObjectDefaults_PersistentVolumeList(in *v1.PersistentVolumeList) {
|
||||
for i := range in.Items {
|
||||
a := &in.Items[i]
|
||||
SetObjectDefaults_PersistentVolume(a)
|
||||
}
|
||||
}
|
||||
|
||||
func SetObjectDefaults_Pod(in *v1.Pod) {
|
||||
SetDefaults_Pod(in)
|
||||
SetDefaults_PodSpec(&in.Spec)
|
||||
for i := range in.Spec.Volumes {
|
||||
a := &in.Spec.Volumes[i]
|
||||
SetDefaults_Volume(a)
|
||||
if a.VolumeSource.HostPath != nil {
|
||||
SetDefaults_HostPathVolumeSource(a.VolumeSource.HostPath)
|
||||
}
|
||||
if a.VolumeSource.Secret != nil {
|
||||
SetDefaults_SecretVolumeSource(a.VolumeSource.Secret)
|
||||
}
|
||||
if a.VolumeSource.ISCSI != nil {
|
||||
SetDefaults_ISCSIVolumeSource(a.VolumeSource.ISCSI)
|
||||
}
|
||||
if a.VolumeSource.RBD != nil {
|
||||
SetDefaults_RBDVolumeSource(a.VolumeSource.RBD)
|
||||
}
|
||||
if a.VolumeSource.DownwardAPI != nil {
|
||||
SetDefaults_DownwardAPIVolumeSource(a.VolumeSource.DownwardAPI)
|
||||
for j := range a.VolumeSource.DownwardAPI.Items {
|
||||
b := &a.VolumeSource.DownwardAPI.Items[j]
|
||||
if b.FieldRef != nil {
|
||||
SetDefaults_ObjectFieldSelector(b.FieldRef)
|
||||
}
|
||||
}
|
||||
}
|
||||
if a.VolumeSource.ConfigMap != nil {
|
||||
SetDefaults_ConfigMapVolumeSource(a.VolumeSource.ConfigMap)
|
||||
}
|
||||
if a.VolumeSource.AzureDisk != nil {
|
||||
SetDefaults_AzureDiskVolumeSource(a.VolumeSource.AzureDisk)
|
||||
}
|
||||
if a.VolumeSource.Projected != nil {
|
||||
SetDefaults_ProjectedVolumeSource(a.VolumeSource.Projected)
|
||||
for j := range a.VolumeSource.Projected.Sources {
|
||||
b := &a.VolumeSource.Projected.Sources[j]
|
||||
if b.DownwardAPI != nil {
|
||||
for k := range b.DownwardAPI.Items {
|
||||
c := &b.DownwardAPI.Items[k]
|
||||
if c.FieldRef != nil {
|
||||
SetDefaults_ObjectFieldSelector(c.FieldRef)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if a.VolumeSource.ScaleIO != nil {
|
||||
SetDefaults_ScaleIOVolumeSource(a.VolumeSource.ScaleIO)
|
||||
}
|
||||
}
|
||||
for i := range in.Spec.InitContainers {
|
||||
a := &in.Spec.InitContainers[i]
|
||||
SetDefaults_Container(a)
|
||||
for j := range a.Ports {
|
||||
b := &a.Ports[j]
|
||||
SetDefaults_ContainerPort(b)
|
||||
}
|
||||
for j := range a.Env {
|
||||
b := &a.Env[j]
|
||||
if b.ValueFrom != nil {
|
||||
if b.ValueFrom.FieldRef != nil {
|
||||
SetDefaults_ObjectFieldSelector(b.ValueFrom.FieldRef)
|
||||
}
|
||||
}
|
||||
}
|
||||
SetDefaults_ResourceList(&a.Resources.Limits)
|
||||
SetDefaults_ResourceList(&a.Resources.Requests)
|
||||
if a.LivenessProbe != nil {
|
||||
SetDefaults_Probe(a.LivenessProbe)
|
||||
if a.LivenessProbe.Handler.HTTPGet != nil {
|
||||
SetDefaults_HTTPGetAction(a.LivenessProbe.Handler.HTTPGet)
|
||||
}
|
||||
}
|
||||
if a.ReadinessProbe != nil {
|
||||
SetDefaults_Probe(a.ReadinessProbe)
|
||||
if a.ReadinessProbe.Handler.HTTPGet != nil {
|
||||
SetDefaults_HTTPGetAction(a.ReadinessProbe.Handler.HTTPGet)
|
||||
}
|
||||
}
|
||||
if a.Lifecycle != nil {
|
||||
if a.Lifecycle.PostStart != nil {
|
||||
if a.Lifecycle.PostStart.HTTPGet != nil {
|
||||
SetDefaults_HTTPGetAction(a.Lifecycle.PostStart.HTTPGet)
|
||||
}
|
||||
}
|
||||
if a.Lifecycle.PreStop != nil {
|
||||
if a.Lifecycle.PreStop.HTTPGet != nil {
|
||||
SetDefaults_HTTPGetAction(a.Lifecycle.PreStop.HTTPGet)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for i := range in.Spec.Containers {
|
||||
a := &in.Spec.Containers[i]
|
||||
SetDefaults_Container(a)
|
||||
for j := range a.Ports {
|
||||
b := &a.Ports[j]
|
||||
SetDefaults_ContainerPort(b)
|
||||
}
|
||||
for j := range a.Env {
|
||||
b := &a.Env[j]
|
||||
if b.ValueFrom != nil {
|
||||
if b.ValueFrom.FieldRef != nil {
|
||||
SetDefaults_ObjectFieldSelector(b.ValueFrom.FieldRef)
|
||||
}
|
||||
}
|
||||
}
|
||||
SetDefaults_ResourceList(&a.Resources.Limits)
|
||||
SetDefaults_ResourceList(&a.Resources.Requests)
|
||||
if a.LivenessProbe != nil {
|
||||
SetDefaults_Probe(a.LivenessProbe)
|
||||
if a.LivenessProbe.Handler.HTTPGet != nil {
|
||||
SetDefaults_HTTPGetAction(a.LivenessProbe.Handler.HTTPGet)
|
||||
}
|
||||
}
|
||||
if a.ReadinessProbe != nil {
|
||||
SetDefaults_Probe(a.ReadinessProbe)
|
||||
if a.ReadinessProbe.Handler.HTTPGet != nil {
|
||||
SetDefaults_HTTPGetAction(a.ReadinessProbe.Handler.HTTPGet)
|
||||
}
|
||||
}
|
||||
if a.Lifecycle != nil {
|
||||
if a.Lifecycle.PostStart != nil {
|
||||
if a.Lifecycle.PostStart.HTTPGet != nil {
|
||||
SetDefaults_HTTPGetAction(a.Lifecycle.PostStart.HTTPGet)
|
||||
}
|
||||
}
|
||||
if a.Lifecycle.PreStop != nil {
|
||||
if a.Lifecycle.PreStop.HTTPGet != nil {
|
||||
SetDefaults_HTTPGetAction(a.Lifecycle.PreStop.HTTPGet)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func SetObjectDefaults_PodAttachOptions(in *v1.PodAttachOptions) {
|
||||
SetDefaults_PodAttachOptions(in)
|
||||
}
|
||||
|
||||
func SetObjectDefaults_PodExecOptions(in *v1.PodExecOptions) {
|
||||
SetDefaults_PodExecOptions(in)
|
||||
}
|
||||
|
||||
func SetObjectDefaults_PodList(in *v1.PodList) {
|
||||
for i := range in.Items {
|
||||
a := &in.Items[i]
|
||||
SetObjectDefaults_Pod(a)
|
||||
}
|
||||
}
|
||||
|
||||
func SetObjectDefaults_PodTemplate(in *v1.PodTemplate) {
|
||||
SetDefaults_PodSpec(&in.Template.Spec)
|
||||
for i := range in.Template.Spec.Volumes {
|
||||
a := &in.Template.Spec.Volumes[i]
|
||||
SetDefaults_Volume(a)
|
||||
if a.VolumeSource.HostPath != nil {
|
||||
SetDefaults_HostPathVolumeSource(a.VolumeSource.HostPath)
|
||||
}
|
||||
if a.VolumeSource.Secret != nil {
|
||||
SetDefaults_SecretVolumeSource(a.VolumeSource.Secret)
|
||||
}
|
||||
if a.VolumeSource.ISCSI != nil {
|
||||
SetDefaults_ISCSIVolumeSource(a.VolumeSource.ISCSI)
|
||||
}
|
||||
if a.VolumeSource.RBD != nil {
|
||||
SetDefaults_RBDVolumeSource(a.VolumeSource.RBD)
|
||||
}
|
||||
if a.VolumeSource.DownwardAPI != nil {
|
||||
SetDefaults_DownwardAPIVolumeSource(a.VolumeSource.DownwardAPI)
|
||||
for j := range a.VolumeSource.DownwardAPI.Items {
|
||||
b := &a.VolumeSource.DownwardAPI.Items[j]
|
||||
if b.FieldRef != nil {
|
||||
SetDefaults_ObjectFieldSelector(b.FieldRef)
|
||||
}
|
||||
}
|
||||
}
|
||||
if a.VolumeSource.ConfigMap != nil {
|
||||
SetDefaults_ConfigMapVolumeSource(a.VolumeSource.ConfigMap)
|
||||
}
|
||||
if a.VolumeSource.AzureDisk != nil {
|
||||
SetDefaults_AzureDiskVolumeSource(a.VolumeSource.AzureDisk)
|
||||
}
|
||||
if a.VolumeSource.Projected != nil {
|
||||
SetDefaults_ProjectedVolumeSource(a.VolumeSource.Projected)
|
||||
for j := range a.VolumeSource.Projected.Sources {
|
||||
b := &a.VolumeSource.Projected.Sources[j]
|
||||
if b.DownwardAPI != nil {
|
||||
for k := range b.DownwardAPI.Items {
|
||||
c := &b.DownwardAPI.Items[k]
|
||||
if c.FieldRef != nil {
|
||||
SetDefaults_ObjectFieldSelector(c.FieldRef)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if a.VolumeSource.ScaleIO != nil {
|
||||
SetDefaults_ScaleIOVolumeSource(a.VolumeSource.ScaleIO)
|
||||
}
|
||||
}
|
||||
for i := range in.Template.Spec.InitContainers {
|
||||
a := &in.Template.Spec.InitContainers[i]
|
||||
SetDefaults_Container(a)
|
||||
for j := range a.Ports {
|
||||
b := &a.Ports[j]
|
||||
SetDefaults_ContainerPort(b)
|
||||
}
|
||||
for j := range a.Env {
|
||||
b := &a.Env[j]
|
||||
if b.ValueFrom != nil {
|
||||
if b.ValueFrom.FieldRef != nil {
|
||||
SetDefaults_ObjectFieldSelector(b.ValueFrom.FieldRef)
|
||||
}
|
||||
}
|
||||
}
|
||||
SetDefaults_ResourceList(&a.Resources.Limits)
|
||||
SetDefaults_ResourceList(&a.Resources.Requests)
|
||||
if a.LivenessProbe != nil {
|
||||
SetDefaults_Probe(a.LivenessProbe)
|
||||
if a.LivenessProbe.Handler.HTTPGet != nil {
|
||||
SetDefaults_HTTPGetAction(a.LivenessProbe.Handler.HTTPGet)
|
||||
}
|
||||
}
|
||||
if a.ReadinessProbe != nil {
|
||||
SetDefaults_Probe(a.ReadinessProbe)
|
||||
if a.ReadinessProbe.Handler.HTTPGet != nil {
|
||||
SetDefaults_HTTPGetAction(a.ReadinessProbe.Handler.HTTPGet)
|
||||
}
|
||||
}
|
||||
if a.Lifecycle != nil {
|
||||
if a.Lifecycle.PostStart != nil {
|
||||
if a.Lifecycle.PostStart.HTTPGet != nil {
|
||||
SetDefaults_HTTPGetAction(a.Lifecycle.PostStart.HTTPGet)
|
||||
}
|
||||
}
|
||||
if a.Lifecycle.PreStop != nil {
|
||||
if a.Lifecycle.PreStop.HTTPGet != nil {
|
||||
SetDefaults_HTTPGetAction(a.Lifecycle.PreStop.HTTPGet)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for i := range in.Template.Spec.Containers {
|
||||
a := &in.Template.Spec.Containers[i]
|
||||
SetDefaults_Container(a)
|
||||
for j := range a.Ports {
|
||||
b := &a.Ports[j]
|
||||
SetDefaults_ContainerPort(b)
|
||||
}
|
||||
for j := range a.Env {
|
||||
b := &a.Env[j]
|
||||
if b.ValueFrom != nil {
|
||||
if b.ValueFrom.FieldRef != nil {
|
||||
SetDefaults_ObjectFieldSelector(b.ValueFrom.FieldRef)
|
||||
}
|
||||
}
|
||||
}
|
||||
SetDefaults_ResourceList(&a.Resources.Limits)
|
||||
SetDefaults_ResourceList(&a.Resources.Requests)
|
||||
if a.LivenessProbe != nil {
|
||||
SetDefaults_Probe(a.LivenessProbe)
|
||||
if a.LivenessProbe.Handler.HTTPGet != nil {
|
||||
SetDefaults_HTTPGetAction(a.LivenessProbe.Handler.HTTPGet)
|
||||
}
|
||||
}
|
||||
if a.ReadinessProbe != nil {
|
||||
SetDefaults_Probe(a.ReadinessProbe)
|
||||
if a.ReadinessProbe.Handler.HTTPGet != nil {
|
||||
SetDefaults_HTTPGetAction(a.ReadinessProbe.Handler.HTTPGet)
|
||||
}
|
||||
}
|
||||
if a.Lifecycle != nil {
|
||||
if a.Lifecycle.PostStart != nil {
|
||||
if a.Lifecycle.PostStart.HTTPGet != nil {
|
||||
SetDefaults_HTTPGetAction(a.Lifecycle.PostStart.HTTPGet)
|
||||
}
|
||||
}
|
||||
if a.Lifecycle.PreStop != nil {
|
||||
if a.Lifecycle.PreStop.HTTPGet != nil {
|
||||
SetDefaults_HTTPGetAction(a.Lifecycle.PreStop.HTTPGet)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func SetObjectDefaults_PodTemplateList(in *v1.PodTemplateList) {
|
||||
for i := range in.Items {
|
||||
a := &in.Items[i]
|
||||
SetObjectDefaults_PodTemplate(a)
|
||||
}
|
||||
}
|
||||
|
||||
func SetObjectDefaults_ReplicationController(in *v1.ReplicationController) {
|
||||
SetDefaults_ReplicationController(in)
|
||||
if in.Spec.Template != nil {
|
||||
SetDefaults_PodSpec(&in.Spec.Template.Spec)
|
||||
for i := range in.Spec.Template.Spec.Volumes {
|
||||
a := &in.Spec.Template.Spec.Volumes[i]
|
||||
SetDefaults_Volume(a)
|
||||
if a.VolumeSource.HostPath != nil {
|
||||
SetDefaults_HostPathVolumeSource(a.VolumeSource.HostPath)
|
||||
}
|
||||
if a.VolumeSource.Secret != nil {
|
||||
SetDefaults_SecretVolumeSource(a.VolumeSource.Secret)
|
||||
}
|
||||
if a.VolumeSource.ISCSI != nil {
|
||||
SetDefaults_ISCSIVolumeSource(a.VolumeSource.ISCSI)
|
||||
}
|
||||
if a.VolumeSource.RBD != nil {
|
||||
SetDefaults_RBDVolumeSource(a.VolumeSource.RBD)
|
||||
}
|
||||
if a.VolumeSource.DownwardAPI != nil {
|
||||
SetDefaults_DownwardAPIVolumeSource(a.VolumeSource.DownwardAPI)
|
||||
for j := range a.VolumeSource.DownwardAPI.Items {
|
||||
b := &a.VolumeSource.DownwardAPI.Items[j]
|
||||
if b.FieldRef != nil {
|
||||
SetDefaults_ObjectFieldSelector(b.FieldRef)
|
||||
}
|
||||
}
|
||||
}
|
||||
if a.VolumeSource.ConfigMap != nil {
|
||||
SetDefaults_ConfigMapVolumeSource(a.VolumeSource.ConfigMap)
|
||||
}
|
||||
if a.VolumeSource.AzureDisk != nil {
|
||||
SetDefaults_AzureDiskVolumeSource(a.VolumeSource.AzureDisk)
|
||||
}
|
||||
if a.VolumeSource.Projected != nil {
|
||||
SetDefaults_ProjectedVolumeSource(a.VolumeSource.Projected)
|
||||
for j := range a.VolumeSource.Projected.Sources {
|
||||
b := &a.VolumeSource.Projected.Sources[j]
|
||||
if b.DownwardAPI != nil {
|
||||
for k := range b.DownwardAPI.Items {
|
||||
c := &b.DownwardAPI.Items[k]
|
||||
if c.FieldRef != nil {
|
||||
SetDefaults_ObjectFieldSelector(c.FieldRef)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if a.VolumeSource.ScaleIO != nil {
|
||||
SetDefaults_ScaleIOVolumeSource(a.VolumeSource.ScaleIO)
|
||||
}
|
||||
}
|
||||
for i := range in.Spec.Template.Spec.InitContainers {
|
||||
a := &in.Spec.Template.Spec.InitContainers[i]
|
||||
SetDefaults_Container(a)
|
||||
for j := range a.Ports {
|
||||
b := &a.Ports[j]
|
||||
SetDefaults_ContainerPort(b)
|
||||
}
|
||||
for j := range a.Env {
|
||||
b := &a.Env[j]
|
||||
if b.ValueFrom != nil {
|
||||
if b.ValueFrom.FieldRef != nil {
|
||||
SetDefaults_ObjectFieldSelector(b.ValueFrom.FieldRef)
|
||||
}
|
||||
}
|
||||
}
|
||||
SetDefaults_ResourceList(&a.Resources.Limits)
|
||||
SetDefaults_ResourceList(&a.Resources.Requests)
|
||||
if a.LivenessProbe != nil {
|
||||
SetDefaults_Probe(a.LivenessProbe)
|
||||
if a.LivenessProbe.Handler.HTTPGet != nil {
|
||||
SetDefaults_HTTPGetAction(a.LivenessProbe.Handler.HTTPGet)
|
||||
}
|
||||
}
|
||||
if a.ReadinessProbe != nil {
|
||||
SetDefaults_Probe(a.ReadinessProbe)
|
||||
if a.ReadinessProbe.Handler.HTTPGet != nil {
|
||||
SetDefaults_HTTPGetAction(a.ReadinessProbe.Handler.HTTPGet)
|
||||
}
|
||||
}
|
||||
if a.Lifecycle != nil {
|
||||
if a.Lifecycle.PostStart != nil {
|
||||
if a.Lifecycle.PostStart.HTTPGet != nil {
|
||||
SetDefaults_HTTPGetAction(a.Lifecycle.PostStart.HTTPGet)
|
||||
}
|
||||
}
|
||||
if a.Lifecycle.PreStop != nil {
|
||||
if a.Lifecycle.PreStop.HTTPGet != nil {
|
||||
SetDefaults_HTTPGetAction(a.Lifecycle.PreStop.HTTPGet)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for i := range in.Spec.Template.Spec.Containers {
|
||||
a := &in.Spec.Template.Spec.Containers[i]
|
||||
SetDefaults_Container(a)
|
||||
for j := range a.Ports {
|
||||
b := &a.Ports[j]
|
||||
SetDefaults_ContainerPort(b)
|
||||
}
|
||||
for j := range a.Env {
|
||||
b := &a.Env[j]
|
||||
if b.ValueFrom != nil {
|
||||
if b.ValueFrom.FieldRef != nil {
|
||||
SetDefaults_ObjectFieldSelector(b.ValueFrom.FieldRef)
|
||||
}
|
||||
}
|
||||
}
|
||||
SetDefaults_ResourceList(&a.Resources.Limits)
|
||||
SetDefaults_ResourceList(&a.Resources.Requests)
|
||||
if a.LivenessProbe != nil {
|
||||
SetDefaults_Probe(a.LivenessProbe)
|
||||
if a.LivenessProbe.Handler.HTTPGet != nil {
|
||||
SetDefaults_HTTPGetAction(a.LivenessProbe.Handler.HTTPGet)
|
||||
}
|
||||
}
|
||||
if a.ReadinessProbe != nil {
|
||||
SetDefaults_Probe(a.ReadinessProbe)
|
||||
if a.ReadinessProbe.Handler.HTTPGet != nil {
|
||||
SetDefaults_HTTPGetAction(a.ReadinessProbe.Handler.HTTPGet)
|
||||
}
|
||||
}
|
||||
if a.Lifecycle != nil {
|
||||
if a.Lifecycle.PostStart != nil {
|
||||
if a.Lifecycle.PostStart.HTTPGet != nil {
|
||||
SetDefaults_HTTPGetAction(a.Lifecycle.PostStart.HTTPGet)
|
||||
}
|
||||
}
|
||||
if a.Lifecycle.PreStop != nil {
|
||||
if a.Lifecycle.PreStop.HTTPGet != nil {
|
||||
SetDefaults_HTTPGetAction(a.Lifecycle.PreStop.HTTPGet)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func SetObjectDefaults_ReplicationControllerList(in *v1.ReplicationControllerList) {
|
||||
for i := range in.Items {
|
||||
a := &in.Items[i]
|
||||
SetObjectDefaults_ReplicationController(a)
|
||||
}
|
||||
}
|
||||
|
||||
func SetObjectDefaults_ResourceQuota(in *v1.ResourceQuota) {
|
||||
SetDefaults_ResourceList(&in.Spec.Hard)
|
||||
SetDefaults_ResourceList(&in.Status.Hard)
|
||||
SetDefaults_ResourceList(&in.Status.Used)
|
||||
}
|
||||
|
||||
func SetObjectDefaults_ResourceQuotaList(in *v1.ResourceQuotaList) {
|
||||
for i := range in.Items {
|
||||
a := &in.Items[i]
|
||||
SetObjectDefaults_ResourceQuota(a)
|
||||
}
|
||||
}
|
||||
|
||||
func SetObjectDefaults_Secret(in *v1.Secret) {
|
||||
SetDefaults_Secret(in)
|
||||
}
|
||||
|
||||
func SetObjectDefaults_SecretList(in *v1.SecretList) {
|
||||
for i := range in.Items {
|
||||
a := &in.Items[i]
|
||||
SetObjectDefaults_Secret(a)
|
||||
}
|
||||
}
|
||||
|
||||
func SetObjectDefaults_Service(in *v1.Service) {
|
||||
SetDefaults_Service(in)
|
||||
}
|
||||
|
||||
func SetObjectDefaults_ServiceList(in *v1.ServiceList) {
|
||||
for i := range in.Items {
|
||||
a := &in.Items[i]
|
||||
SetObjectDefaults_Service(a)
|
||||
}
|
||||
}
|
||||
79
vendor/k8s.io/kubernetes/pkg/api/validation/BUILD
generated
vendored
79
vendor/k8s.io/kubernetes/pkg/api/validation/BUILD
generated
vendored
|
|
@ -1,79 +0,0 @@
|
|||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
"go_test",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"doc.go",
|
||||
"events.go",
|
||||
"validation.go",
|
||||
],
|
||||
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",
|
||||
"//pkg/features:go_default_library",
|
||||
"//pkg/security/apparmor:go_default_library",
|
||||
"//vendor/github.com/golang/glog: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/meta:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/resource:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/validation:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1/validation:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/labels:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/diff:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/intstr:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/validation:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/validation/field:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/util/feature:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = [
|
||||
"events_test.go",
|
||||
"validation_test.go",
|
||||
],
|
||||
library = ":go_default_library",
|
||||
deps = [
|
||||
"//pkg/api:go_default_library",
|
||||
"//pkg/api/helper:go_default_library",
|
||||
"//pkg/api/testapi:go_default_library",
|
||||
"//pkg/capabilities:go_default_library",
|
||||
"//pkg/security/apparmor:go_default_library",
|
||||
"//vendor/k8s.io/api/core/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/resource:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/intstr:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/validation:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/validation/field:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/util/feature:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
37
vendor/k8s.io/kubernetes/pkg/api/validation/OWNERS
generated
vendored
37
vendor/k8s.io/kubernetes/pkg/api/validation/OWNERS
generated
vendored
|
|
@ -1,37 +0,0 @@
|
|||
reviewers:
|
||||
- thockin
|
||||
- lavalamp
|
||||
- smarterclayton
|
||||
- wojtek-t
|
||||
- deads2k
|
||||
- yujuhong
|
||||
- brendandburns
|
||||
- derekwaynecarr
|
||||
- caesarxuchao
|
||||
- vishh
|
||||
- mikedanese
|
||||
- liggitt
|
||||
- nikhiljindal
|
||||
- gmarek
|
||||
- erictune
|
||||
- davidopp
|
||||
- pmorie
|
||||
- sttts
|
||||
- quinton-hoole
|
||||
- dchen1107
|
||||
- zmerlynn
|
||||
- janetkuo
|
||||
- justinsb
|
||||
- pwittrock
|
||||
- roberthbailey
|
||||
- tallclair
|
||||
- eparis
|
||||
- soltysh
|
||||
- piosz
|
||||
- jsafrane
|
||||
- jbeda
|
||||
- dims
|
||||
- fejta
|
||||
- krousey
|
||||
- rootfs
|
||||
- markturansky
|
||||
19
vendor/k8s.io/kubernetes/pkg/api/validation/doc.go
generated
vendored
19
vendor/k8s.io/kubernetes/pkg/api/validation/doc.go
generated
vendored
|
|
@ -1,19 +0,0 @@
|
|||
/*
|
||||
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 validation has functions for validating the correctness of api
|
||||
// objects and explaining what is wrong with them when they aren't valid.
|
||||
package validation // import "k8s.io/kubernetes/pkg/api/validation"
|
||||
80
vendor/k8s.io/kubernetes/pkg/api/validation/events.go
generated
vendored
80
vendor/k8s.io/kubernetes/pkg/api/validation/events.go
generated
vendored
|
|
@ -1,80 +0,0 @@
|
|||
/*
|
||||
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 validation
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"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.
|
||||
func ValidateEvent(event *api.Event) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
|
||||
// Make sure event.Namespace and the involvedObject.Namespace agree
|
||||
if len(event.InvolvedObject.Namespace) == 0 {
|
||||
// event.Namespace must also be empty (or "default", for compatibility with old clients)
|
||||
if event.Namespace != metav1.NamespaceNone && event.Namespace != metav1.NamespaceDefault {
|
||||
allErrs = append(allErrs, field.Invalid(field.NewPath("involvedObject", "namespace"), event.InvolvedObject.Namespace, "does not match event.namespace"))
|
||||
}
|
||||
} else {
|
||||
// event namespace must match
|
||||
if event.Namespace != event.InvolvedObject.Namespace {
|
||||
allErrs = append(allErrs, field.Invalid(field.NewPath("involvedObject", "namespace"), event.InvolvedObject.Namespace, "does not match event.namespace"))
|
||||
}
|
||||
}
|
||||
|
||||
// For kinds we recognize, make sure involvedObject.Namespace is set for namespaced kinds
|
||||
if namespaced, err := isNamespacedKind(event.InvolvedObject.Kind, event.InvolvedObject.APIVersion); err == nil {
|
||||
if namespaced && len(event.InvolvedObject.Namespace) == 0 {
|
||||
allErrs = append(allErrs, field.Required(field.NewPath("involvedObject", "namespace"), fmt.Sprintf("required for kind %s", event.InvolvedObject.Kind)))
|
||||
}
|
||||
if !namespaced && len(event.InvolvedObject.Namespace) > 0 {
|
||||
allErrs = append(allErrs, field.Invalid(field.NewPath("involvedObject", "namespace"), event.InvolvedObject.Namespace, fmt.Sprintf("not allowed for kind %s", event.InvolvedObject.Kind)))
|
||||
}
|
||||
}
|
||||
|
||||
for _, msg := range validation.IsDNS1123Subdomain(event.Namespace) {
|
||||
allErrs = append(allErrs, field.Invalid(field.NewPath("namespace"), event.Namespace, msg))
|
||||
}
|
||||
return allErrs
|
||||
}
|
||||
|
||||
// Check whether the kind in groupVersion is scoped at the root of the api hierarchy
|
||||
func isNamespacedKind(kind, groupVersion string) (bool, error) {
|
||||
group := apiutil.GetGroup(groupVersion)
|
||||
g, err := api.Registry.Group(group)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
restMapping, err := g.RESTMapper.RESTMapping(schema.GroupKind{Group: group, Kind: kind}, apiutil.GetVersion(groupVersion))
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
scopeName := restMapping.Scope.Name()
|
||||
if scopeName == meta.RESTScopeNameNamespace {
|
||||
return true, nil
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
221
vendor/k8s.io/kubernetes/pkg/api/validation/events_test.go
generated
vendored
221
vendor/k8s.io/kubernetes/pkg/api/validation/events_test.go
generated
vendored
|
|
@ -1,221 +0,0 @@
|
|||
/*
|
||||
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 validation
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
)
|
||||
|
||||
func TestValidateEvent(t *testing.T) {
|
||||
table := []struct {
|
||||
*api.Event
|
||||
valid bool
|
||||
}{
|
||||
{
|
||||
&api.Event{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test1",
|
||||
Namespace: "foo",
|
||||
},
|
||||
InvolvedObject: api.ObjectReference{
|
||||
Namespace: "bar",
|
||||
Kind: "Pod",
|
||||
},
|
||||
},
|
||||
false,
|
||||
}, {
|
||||
&api.Event{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test2",
|
||||
Namespace: "aoeu-_-aoeu",
|
||||
},
|
||||
InvolvedObject: api.ObjectReference{
|
||||
Namespace: "aoeu-_-aoeu",
|
||||
Kind: "Pod",
|
||||
},
|
||||
},
|
||||
false,
|
||||
}, {
|
||||
&api.Event{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test3",
|
||||
Namespace: metav1.NamespaceDefault,
|
||||
},
|
||||
InvolvedObject: api.ObjectReference{
|
||||
APIVersion: "v1",
|
||||
Kind: "Node",
|
||||
},
|
||||
},
|
||||
true,
|
||||
}, {
|
||||
&api.Event{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test4",
|
||||
Namespace: metav1.NamespaceDefault,
|
||||
},
|
||||
InvolvedObject: api.ObjectReference{
|
||||
APIVersion: "v1",
|
||||
Kind: "Namespace",
|
||||
},
|
||||
},
|
||||
true,
|
||||
}, {
|
||||
&api.Event{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test5",
|
||||
Namespace: metav1.NamespaceDefault,
|
||||
},
|
||||
InvolvedObject: api.ObjectReference{
|
||||
APIVersion: "extensions/v1beta1",
|
||||
Kind: "NoKind",
|
||||
Namespace: metav1.NamespaceDefault,
|
||||
},
|
||||
},
|
||||
true,
|
||||
}, {
|
||||
&api.Event{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test6",
|
||||
Namespace: metav1.NamespaceDefault,
|
||||
},
|
||||
InvolvedObject: api.ObjectReference{
|
||||
APIVersion: "extensions/v1beta1",
|
||||
Kind: "Job",
|
||||
Namespace: "foo",
|
||||
},
|
||||
},
|
||||
false,
|
||||
}, {
|
||||
&api.Event{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test7",
|
||||
Namespace: metav1.NamespaceDefault,
|
||||
},
|
||||
InvolvedObject: api.ObjectReference{
|
||||
APIVersion: "extensions/v1beta1",
|
||||
Kind: "Job",
|
||||
Namespace: metav1.NamespaceDefault,
|
||||
},
|
||||
},
|
||||
true,
|
||||
}, {
|
||||
&api.Event{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test8",
|
||||
Namespace: metav1.NamespaceDefault,
|
||||
},
|
||||
InvolvedObject: api.ObjectReference{
|
||||
APIVersion: "other/v1beta1",
|
||||
Kind: "Job",
|
||||
Namespace: "foo",
|
||||
},
|
||||
},
|
||||
false,
|
||||
}, {
|
||||
&api.Event{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test9",
|
||||
Namespace: "foo",
|
||||
},
|
||||
InvolvedObject: api.ObjectReference{
|
||||
APIVersion: "other/v1beta1",
|
||||
Kind: "Job",
|
||||
Namespace: "foo",
|
||||
},
|
||||
},
|
||||
true,
|
||||
}, {
|
||||
&api.Event{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test10",
|
||||
Namespace: metav1.NamespaceDefault,
|
||||
},
|
||||
InvolvedObject: api.ObjectReference{
|
||||
APIVersion: "extensions",
|
||||
Kind: "Job",
|
||||
Namespace: "foo",
|
||||
},
|
||||
},
|
||||
false,
|
||||
}, {
|
||||
&api.Event{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test11",
|
||||
Namespace: "foo",
|
||||
},
|
||||
InvolvedObject: api.ObjectReference{
|
||||
// must register in v1beta1 to be true
|
||||
APIVersion: "extensions/v1beta1",
|
||||
Kind: "Job",
|
||||
Namespace: "foo",
|
||||
},
|
||||
},
|
||||
true,
|
||||
},
|
||||
{
|
||||
&api.Event{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test12",
|
||||
Namespace: "foo",
|
||||
},
|
||||
InvolvedObject: api.ObjectReference{
|
||||
APIVersion: "other/v1beta1",
|
||||
Kind: "FooBar",
|
||||
Namespace: "bar",
|
||||
},
|
||||
},
|
||||
false,
|
||||
},
|
||||
{
|
||||
&api.Event{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test13",
|
||||
Namespace: "",
|
||||
},
|
||||
InvolvedObject: api.ObjectReference{
|
||||
APIVersion: "other/v1beta1",
|
||||
Kind: "FooBar",
|
||||
Namespace: "bar",
|
||||
},
|
||||
},
|
||||
false,
|
||||
},
|
||||
{
|
||||
&api.Event{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test14",
|
||||
Namespace: "foo",
|
||||
},
|
||||
InvolvedObject: api.ObjectReference{
|
||||
APIVersion: "other/v1beta1",
|
||||
Kind: "FooBar",
|
||||
Namespace: "",
|
||||
},
|
||||
},
|
||||
false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, item := range table {
|
||||
if e, a := item.valid, len(ValidateEvent(item.Event)) == 0; e != a {
|
||||
t.Errorf("%v: expected %v, got %v", item.Event.Name, e, a)
|
||||
}
|
||||
}
|
||||
}
|
||||
4479
vendor/k8s.io/kubernetes/pkg/api/validation/validation.go
generated
vendored
4479
vendor/k8s.io/kubernetes/pkg/api/validation/validation.go
generated
vendored
File diff suppressed because it is too large
Load diff
11084
vendor/k8s.io/kubernetes/pkg/api/validation/validation_test.go
generated
vendored
11084
vendor/k8s.io/kubernetes/pkg/api/validation/validation_test.go
generated
vendored
File diff suppressed because it is too large
Load diff
6320
vendor/k8s.io/kubernetes/pkg/api/zz_generated.deepcopy.go
generated
vendored
6320
vendor/k8s.io/kubernetes/pkg/api/zz_generated.deepcopy.go
generated
vendored
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue