Merge pull request #44296 from caesarxuchao/move-api-helpers.go
Automatic merge from submit-queue
Move api helpers.go to a subpackage
Part of https://github.com/kubernetes/kubernetes/issues/44065.
This PR moves the pkg/api/helpers.go to its own subpackage. It's mostly a mechanic move, except that
* I removed ConversionError in helpers.go, it's not used by anyone
* I moved the 3 methods of Taint and Toleration to pkg/api/methods.go, and left a TODO saying refactoring these methods to functions.
I'll send a few more PRs to make the k8s.io/kubernetes/pkg/api package only contains the code we want in the k8s.io/api repo, then we can run a [script](a0015fd1be (diff-7a2fbb4371972350ee414c6b88aee1c8)
) to cut the new repo.
This commit is contained in:
commit
abd92fab1e
@ -47,6 +47,7 @@ go_test(
|
|||||||
"//federation/pkg/kubefed/testing:go_default_library",
|
"//federation/pkg/kubefed/testing:go_default_library",
|
||||||
"//federation/pkg/kubefed/util:go_default_library",
|
"//federation/pkg/kubefed/util:go_default_library",
|
||||||
"//pkg/api:go_default_library",
|
"//pkg/api:go_default_library",
|
||||||
|
"//pkg/api/helper:go_default_library",
|
||||||
"//pkg/api/testapi:go_default_library",
|
"//pkg/api/testapi:go_default_library",
|
||||||
"//pkg/api/v1:go_default_library",
|
"//pkg/api/v1:go_default_library",
|
||||||
"//pkg/apis/extensions/v1beta1:go_default_library",
|
"//pkg/apis/extensions/v1beta1:go_default_library",
|
||||||
|
@ -46,6 +46,7 @@ import (
|
|||||||
kubefedtesting "k8s.io/kubernetes/federation/pkg/kubefed/testing"
|
kubefedtesting "k8s.io/kubernetes/federation/pkg/kubefed/testing"
|
||||||
"k8s.io/kubernetes/federation/pkg/kubefed/util"
|
"k8s.io/kubernetes/federation/pkg/kubefed/util"
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
|
"k8s.io/kubernetes/pkg/api/helper"
|
||||||
"k8s.io/kubernetes/pkg/api/testapi"
|
"k8s.io/kubernetes/pkg/api/testapi"
|
||||||
"k8s.io/kubernetes/pkg/api/v1"
|
"k8s.io/kubernetes/pkg/api/v1"
|
||||||
"k8s.io/kubernetes/pkg/apis/extensions/v1beta1"
|
"k8s.io/kubernetes/pkg/apis/extensions/v1beta1"
|
||||||
@ -1243,7 +1244,7 @@ func fakeInitHostFactory(apiserverServiceType v1.ServiceType, federationName, na
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if !api.Semantic.DeepEqual(got, sa) {
|
if !helper.Semantic.DeepEqual(got, sa) {
|
||||||
return nil, fmt.Errorf("unexpected service account object\n\tDiff: %s", diff.ObjectGoPrintDiff(got, sa))
|
return nil, fmt.Errorf("unexpected service account object\n\tDiff: %s", diff.ObjectGoPrintDiff(got, sa))
|
||||||
}
|
}
|
||||||
return &http.Response{StatusCode: http.StatusCreated, Header: kubefedtesting.DefaultHeader(), Body: kubefedtesting.ObjBody(codec, &sa)}, nil
|
return &http.Response{StatusCode: http.StatusCreated, Header: kubefedtesting.DefaultHeader(), Body: kubefedtesting.ObjBody(codec, &sa)}, nil
|
||||||
@ -1257,7 +1258,7 @@ func fakeInitHostFactory(apiserverServiceType v1.ServiceType, federationName, na
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if !api.Semantic.DeepEqual(got, role) {
|
if !helper.Semantic.DeepEqual(got, role) {
|
||||||
return nil, fmt.Errorf("unexpected role object\n\tDiff: %s", diff.ObjectGoPrintDiff(got, role))
|
return nil, fmt.Errorf("unexpected role object\n\tDiff: %s", diff.ObjectGoPrintDiff(got, role))
|
||||||
}
|
}
|
||||||
return &http.Response{StatusCode: http.StatusCreated, Header: kubefedtesting.DefaultHeader(), Body: kubefedtesting.ObjBody(rbacCodec, &role)}, nil
|
return &http.Response{StatusCode: http.StatusCreated, Header: kubefedtesting.DefaultHeader(), Body: kubefedtesting.ObjBody(rbacCodec, &role)}, nil
|
||||||
@ -1271,7 +1272,7 @@ func fakeInitHostFactory(apiserverServiceType v1.ServiceType, federationName, na
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if !api.Semantic.DeepEqual(got, rolebinding) {
|
if !helper.Semantic.DeepEqual(got, rolebinding) {
|
||||||
return nil, fmt.Errorf("unexpected rolebinding object\n\tDiff: %s", diff.ObjectGoPrintDiff(got, rolebinding))
|
return nil, fmt.Errorf("unexpected rolebinding object\n\tDiff: %s", diff.ObjectGoPrintDiff(got, rolebinding))
|
||||||
}
|
}
|
||||||
return &http.Response{StatusCode: http.StatusCreated, Header: kubefedtesting.DefaultHeader(), Body: kubefedtesting.ObjBody(rbacCodec, &rolebinding)}, nil
|
return &http.Response{StatusCode: http.StatusCreated, Header: kubefedtesting.DefaultHeader(), Body: kubefedtesting.ObjBody(rbacCodec, &rolebinding)}, nil
|
||||||
|
@ -15,8 +15,8 @@ go_library(
|
|||||||
"defaults.go",
|
"defaults.go",
|
||||||
"doc.go",
|
"doc.go",
|
||||||
"field_constants.go",
|
"field_constants.go",
|
||||||
"helpers.go",
|
|
||||||
"json.go",
|
"json.go",
|
||||||
|
"methods.go",
|
||||||
"ref.go",
|
"ref.go",
|
||||||
"register.go",
|
"register.go",
|
||||||
"resource_helpers.go",
|
"resource_helpers.go",
|
||||||
@ -25,7 +25,6 @@ go_library(
|
|||||||
],
|
],
|
||||||
tags = ["automanaged"],
|
tags = ["automanaged"],
|
||||||
deps = [
|
deps = [
|
||||||
"//vendor:github.com/davecgh/go-spew/spew",
|
|
||||||
"//vendor:k8s.io/apimachinery/pkg/api/meta",
|
"//vendor:k8s.io/apimachinery/pkg/api/meta",
|
||||||
"//vendor:k8s.io/apimachinery/pkg/api/resource",
|
"//vendor:k8s.io/apimachinery/pkg/api/resource",
|
||||||
"//vendor:k8s.io/apimachinery/pkg/apimachinery/announced",
|
"//vendor:k8s.io/apimachinery/pkg/apimachinery/announced",
|
||||||
@ -37,17 +36,15 @@ go_library(
|
|||||||
"//vendor:k8s.io/apimachinery/pkg/runtime",
|
"//vendor:k8s.io/apimachinery/pkg/runtime",
|
||||||
"//vendor:k8s.io/apimachinery/pkg/runtime/schema",
|
"//vendor:k8s.io/apimachinery/pkg/runtime/schema",
|
||||||
"//vendor:k8s.io/apimachinery/pkg/runtime/serializer",
|
"//vendor:k8s.io/apimachinery/pkg/runtime/serializer",
|
||||||
"//vendor:k8s.io/apimachinery/pkg/selection",
|
|
||||||
"//vendor:k8s.io/apimachinery/pkg/types",
|
"//vendor:k8s.io/apimachinery/pkg/types",
|
||||||
"//vendor:k8s.io/apimachinery/pkg/util/intstr",
|
"//vendor:k8s.io/apimachinery/pkg/util/intstr",
|
||||||
"//vendor:k8s.io/apimachinery/pkg/util/sets",
|
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
go_test(
|
go_test(
|
||||||
name = "go_default_test",
|
name = "go_default_test",
|
||||||
srcs = [
|
srcs = [
|
||||||
"helpers_test.go",
|
"methods_test.go",
|
||||||
"ref_test.go",
|
"ref_test.go",
|
||||||
"resource_helpers_test.go",
|
"resource_helpers_test.go",
|
||||||
],
|
],
|
||||||
@ -56,7 +53,6 @@ go_test(
|
|||||||
deps = [
|
deps = [
|
||||||
"//vendor:k8s.io/apimachinery/pkg/api/resource",
|
"//vendor:k8s.io/apimachinery/pkg/api/resource",
|
||||||
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
|
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
|
||||||
"//vendor:k8s.io/apimachinery/pkg/labels",
|
|
||||||
"//vendor:k8s.io/apimachinery/pkg/runtime",
|
"//vendor:k8s.io/apimachinery/pkg/runtime",
|
||||||
"//vendor:k8s.io/apimachinery/pkg/runtime/schema",
|
"//vendor:k8s.io/apimachinery/pkg/runtime/schema",
|
||||||
],
|
],
|
||||||
@ -120,6 +116,7 @@ filegroup(
|
|||||||
"//pkg/api/endpoints:all-srcs",
|
"//pkg/api/endpoints:all-srcs",
|
||||||
"//pkg/api/errors:all-srcs",
|
"//pkg/api/errors:all-srcs",
|
||||||
"//pkg/api/events:all-srcs",
|
"//pkg/api/events:all-srcs",
|
||||||
|
"//pkg/api/helper:all-srcs",
|
||||||
"//pkg/api/install:all-srcs",
|
"//pkg/api/install:all-srcs",
|
||||||
"//pkg/api/meta:all-srcs",
|
"//pkg/api/meta:all-srcs",
|
||||||
"//pkg/api/pod:all-srcs",
|
"//pkg/api/pod:all-srcs",
|
||||||
|
@ -64,4 +64,7 @@ const (
|
|||||||
// in the Annotations of a Pod.
|
// in the Annotations of a Pod.
|
||||||
// TODO: remove when alpha support for affinity is removed
|
// TODO: remove when alpha support for affinity is removed
|
||||||
AffinityAnnotationKey string = "scheduler.alpha.kubernetes.io/affinity"
|
AffinityAnnotationKey string = "scheduler.alpha.kubernetes.io/affinity"
|
||||||
|
|
||||||
|
// annotation key prefix used to identify non-convertible json paths.
|
||||||
|
NonConvertibleAnnotationPrefix = "non-convertible.kubernetes.io"
|
||||||
)
|
)
|
||||||
|
51
pkg/api/helper/BUILD
Normal file
51
pkg/api/helper/BUILD
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
package(default_visibility = ["//visibility:public"])
|
||||||
|
|
||||||
|
licenses(["notice"])
|
||||||
|
|
||||||
|
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",
|
||||||
|
tags = ["automanaged"],
|
||||||
|
deps = [
|
||||||
|
"//pkg/api:go_default_library",
|
||||||
|
"//vendor:k8s.io/apimachinery/pkg/api/resource",
|
||||||
|
"//vendor:k8s.io/apimachinery/pkg/labels",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
go_library(
|
||||||
|
name = "go_default_library",
|
||||||
|
srcs = ["helpers.go"],
|
||||||
|
tags = ["automanaged"],
|
||||||
|
deps = [
|
||||||
|
"//pkg/api:go_default_library",
|
||||||
|
"//vendor:k8s.io/apimachinery/pkg/api/resource",
|
||||||
|
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
|
||||||
|
"//vendor:k8s.io/apimachinery/pkg/conversion",
|
||||||
|
"//vendor:k8s.io/apimachinery/pkg/fields",
|
||||||
|
"//vendor:k8s.io/apimachinery/pkg/labels",
|
||||||
|
"//vendor:k8s.io/apimachinery/pkg/runtime",
|
||||||
|
"//vendor:k8s.io/apimachinery/pkg/selection",
|
||||||
|
"//vendor:k8s.io/apimachinery/pkg/util/sets",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
filegroup(
|
||||||
|
name = "package-srcs",
|
||||||
|
srcs = glob(["**"]),
|
||||||
|
tags = ["automanaged"],
|
||||||
|
visibility = ["//visibility:private"],
|
||||||
|
)
|
||||||
|
|
||||||
|
filegroup(
|
||||||
|
name = "all-srcs",
|
||||||
|
srcs = [":package-srcs"],
|
||||||
|
tags = ["automanaged"],
|
||||||
|
)
|
@ -14,18 +14,15 @@ See the License for the specific language governing permissions and
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package api
|
package helper
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/md5"
|
"crypto/md5"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"reflect"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/davecgh/go-spew/spew"
|
|
||||||
|
|
||||||
"k8s.io/apimachinery/pkg/api/resource"
|
"k8s.io/apimachinery/pkg/api/resource"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/conversion"
|
"k8s.io/apimachinery/pkg/conversion"
|
||||||
@ -34,25 +31,7 @@ import (
|
|||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
"k8s.io/apimachinery/pkg/selection"
|
"k8s.io/apimachinery/pkg/selection"
|
||||||
"k8s.io/apimachinery/pkg/util/sets"
|
"k8s.io/apimachinery/pkg/util/sets"
|
||||||
)
|
"k8s.io/kubernetes/pkg/api"
|
||||||
|
|
||||||
// Conversion error conveniently packages up errors in conversions.
|
|
||||||
type ConversionError struct {
|
|
||||||
In, Out interface{}
|
|
||||||
Message string
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return a helpful string about the error
|
|
||||||
func (c *ConversionError) Error() string {
|
|
||||||
return spew.Sprintf(
|
|
||||||
"Conversion error: %s. (in: %v(%+v) out: %v)",
|
|
||||||
c.Message, reflect.TypeOf(c.In), c.In, reflect.TypeOf(c.Out),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
|
||||||
// annotation key prefix used to identify non-convertible json paths.
|
|
||||||
NonConvertibleAnnotationPrefix = "non-convertible.kubernetes.io"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// NonConvertibleFields iterates over the provided map and filters out all but
|
// NonConvertibleFields iterates over the provided map and filters out all but
|
||||||
@ -60,7 +39,7 @@ const (
|
|||||||
func NonConvertibleFields(annotations map[string]string) map[string]string {
|
func NonConvertibleFields(annotations map[string]string) map[string]string {
|
||||||
nonConvertibleKeys := map[string]string{}
|
nonConvertibleKeys := map[string]string{}
|
||||||
for key, value := range annotations {
|
for key, value := range annotations {
|
||||||
if strings.HasPrefix(key, NonConvertibleAnnotationPrefix) {
|
if strings.HasPrefix(key, api.NonConvertibleAnnotationPrefix) {
|
||||||
nonConvertibleKeys[key] = value
|
nonConvertibleKeys[key] = value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -89,10 +68,10 @@ var Semantic = conversion.EqualitiesOrDie(
|
|||||||
)
|
)
|
||||||
|
|
||||||
var standardResourceQuotaScopes = sets.NewString(
|
var standardResourceQuotaScopes = sets.NewString(
|
||||||
string(ResourceQuotaScopeTerminating),
|
string(api.ResourceQuotaScopeTerminating),
|
||||||
string(ResourceQuotaScopeNotTerminating),
|
string(api.ResourceQuotaScopeNotTerminating),
|
||||||
string(ResourceQuotaScopeBestEffort),
|
string(api.ResourceQuotaScopeBestEffort),
|
||||||
string(ResourceQuotaScopeNotBestEffort),
|
string(api.ResourceQuotaScopeNotBestEffort),
|
||||||
)
|
)
|
||||||
|
|
||||||
// IsStandardResourceQuotaScope returns true if the scope is a standard value
|
// IsStandardResourceQuotaScope returns true if the scope is a standard value
|
||||||
@ -101,24 +80,24 @@ func IsStandardResourceQuotaScope(str string) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var podObjectCountQuotaResources = sets.NewString(
|
var podObjectCountQuotaResources = sets.NewString(
|
||||||
string(ResourcePods),
|
string(api.ResourcePods),
|
||||||
)
|
)
|
||||||
|
|
||||||
var podComputeQuotaResources = sets.NewString(
|
var podComputeQuotaResources = sets.NewString(
|
||||||
string(ResourceCPU),
|
string(api.ResourceCPU),
|
||||||
string(ResourceMemory),
|
string(api.ResourceMemory),
|
||||||
string(ResourceLimitsCPU),
|
string(api.ResourceLimitsCPU),
|
||||||
string(ResourceLimitsMemory),
|
string(api.ResourceLimitsMemory),
|
||||||
string(ResourceRequestsCPU),
|
string(api.ResourceRequestsCPU),
|
||||||
string(ResourceRequestsMemory),
|
string(api.ResourceRequestsMemory),
|
||||||
)
|
)
|
||||||
|
|
||||||
// IsResourceQuotaScopeValidForResource returns true if the resource applies to the specified scope
|
// IsResourceQuotaScopeValidForResource returns true if the resource applies to the specified scope
|
||||||
func IsResourceQuotaScopeValidForResource(scope ResourceQuotaScope, resource string) bool {
|
func IsResourceQuotaScopeValidForResource(scope api.ResourceQuotaScope, resource string) bool {
|
||||||
switch scope {
|
switch scope {
|
||||||
case ResourceQuotaScopeTerminating, ResourceQuotaScopeNotTerminating, ResourceQuotaScopeNotBestEffort:
|
case api.ResourceQuotaScopeTerminating, api.ResourceQuotaScopeNotTerminating, api.ResourceQuotaScopeNotBestEffort:
|
||||||
return podObjectCountQuotaResources.Has(resource) || podComputeQuotaResources.Has(resource)
|
return podObjectCountQuotaResources.Has(resource) || podComputeQuotaResources.Has(resource)
|
||||||
case ResourceQuotaScopeBestEffort:
|
case api.ResourceQuotaScopeBestEffort:
|
||||||
return podObjectCountQuotaResources.Has(resource)
|
return podObjectCountQuotaResources.Has(resource)
|
||||||
default:
|
default:
|
||||||
return true
|
return true
|
||||||
@ -126,8 +105,8 @@ func IsResourceQuotaScopeValidForResource(scope ResourceQuotaScope, resource str
|
|||||||
}
|
}
|
||||||
|
|
||||||
var standardContainerResources = sets.NewString(
|
var standardContainerResources = sets.NewString(
|
||||||
string(ResourceCPU),
|
string(api.ResourceCPU),
|
||||||
string(ResourceMemory),
|
string(api.ResourceMemory),
|
||||||
)
|
)
|
||||||
|
|
||||||
// IsStandardContainerResourceName returns true if the container can make a resource request
|
// IsStandardContainerResourceName returns true if the container can make a resource request
|
||||||
@ -138,24 +117,24 @@ func IsStandardContainerResourceName(str string) bool {
|
|||||||
|
|
||||||
// IsOpaqueIntResourceName returns true if the resource name has the opaque
|
// IsOpaqueIntResourceName returns true if the resource name has the opaque
|
||||||
// integer resource prefix.
|
// integer resource prefix.
|
||||||
func IsOpaqueIntResourceName(name ResourceName) bool {
|
func IsOpaqueIntResourceName(name api.ResourceName) bool {
|
||||||
return strings.HasPrefix(string(name), ResourceOpaqueIntPrefix)
|
return strings.HasPrefix(string(name), api.ResourceOpaqueIntPrefix)
|
||||||
}
|
}
|
||||||
|
|
||||||
// OpaqueIntResourceName returns a ResourceName with the canonical opaque
|
// OpaqueIntResourceName returns a ResourceName with the canonical opaque
|
||||||
// integer prefix prepended. If the argument already has the prefix, it is
|
// integer prefix prepended. If the argument already has the prefix, it is
|
||||||
// returned unmodified.
|
// returned unmodified.
|
||||||
func OpaqueIntResourceName(name string) ResourceName {
|
func OpaqueIntResourceName(name string) api.ResourceName {
|
||||||
if IsOpaqueIntResourceName(ResourceName(name)) {
|
if IsOpaqueIntResourceName(api.ResourceName(name)) {
|
||||||
return ResourceName(name)
|
return api.ResourceName(name)
|
||||||
}
|
}
|
||||||
return ResourceName(fmt.Sprintf("%s%s", ResourceOpaqueIntPrefix, name))
|
return api.ResourceName(fmt.Sprintf("%s%s", api.ResourceOpaqueIntPrefix, name))
|
||||||
}
|
}
|
||||||
|
|
||||||
var standardLimitRangeTypes = sets.NewString(
|
var standardLimitRangeTypes = sets.NewString(
|
||||||
string(LimitTypePod),
|
string(api.LimitTypePod),
|
||||||
string(LimitTypeContainer),
|
string(api.LimitTypeContainer),
|
||||||
string(LimitTypePersistentVolumeClaim),
|
string(api.LimitTypePersistentVolumeClaim),
|
||||||
)
|
)
|
||||||
|
|
||||||
// IsStandardLimitRangeType returns true if the type is Pod or Container
|
// IsStandardLimitRangeType returns true if the type is Pod or Container
|
||||||
@ -164,22 +143,22 @@ func IsStandardLimitRangeType(str string) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var standardQuotaResources = sets.NewString(
|
var standardQuotaResources = sets.NewString(
|
||||||
string(ResourceCPU),
|
string(api.ResourceCPU),
|
||||||
string(ResourceMemory),
|
string(api.ResourceMemory),
|
||||||
string(ResourceRequestsCPU),
|
string(api.ResourceRequestsCPU),
|
||||||
string(ResourceRequestsMemory),
|
string(api.ResourceRequestsMemory),
|
||||||
string(ResourceRequestsStorage),
|
string(api.ResourceRequestsStorage),
|
||||||
string(ResourceLimitsCPU),
|
string(api.ResourceLimitsCPU),
|
||||||
string(ResourceLimitsMemory),
|
string(api.ResourceLimitsMemory),
|
||||||
string(ResourcePods),
|
string(api.ResourcePods),
|
||||||
string(ResourceQuotas),
|
string(api.ResourceQuotas),
|
||||||
string(ResourceServices),
|
string(api.ResourceServices),
|
||||||
string(ResourceReplicationControllers),
|
string(api.ResourceReplicationControllers),
|
||||||
string(ResourceSecrets),
|
string(api.ResourceSecrets),
|
||||||
string(ResourcePersistentVolumeClaims),
|
string(api.ResourcePersistentVolumeClaims),
|
||||||
string(ResourceConfigMaps),
|
string(api.ResourceConfigMaps),
|
||||||
string(ResourceServicesNodePorts),
|
string(api.ResourceServicesNodePorts),
|
||||||
string(ResourceServicesLoadBalancers),
|
string(api.ResourceServicesLoadBalancers),
|
||||||
)
|
)
|
||||||
|
|
||||||
// IsStandardQuotaResourceName returns true if the resource is known to
|
// IsStandardQuotaResourceName returns true if the resource is known to
|
||||||
@ -189,21 +168,21 @@ func IsStandardQuotaResourceName(str string) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var standardResources = sets.NewString(
|
var standardResources = sets.NewString(
|
||||||
string(ResourceCPU),
|
string(api.ResourceCPU),
|
||||||
string(ResourceMemory),
|
string(api.ResourceMemory),
|
||||||
string(ResourceRequestsCPU),
|
string(api.ResourceRequestsCPU),
|
||||||
string(ResourceRequestsMemory),
|
string(api.ResourceRequestsMemory),
|
||||||
string(ResourceLimitsCPU),
|
string(api.ResourceLimitsCPU),
|
||||||
string(ResourceLimitsMemory),
|
string(api.ResourceLimitsMemory),
|
||||||
string(ResourcePods),
|
string(api.ResourcePods),
|
||||||
string(ResourceQuotas),
|
string(api.ResourceQuotas),
|
||||||
string(ResourceServices),
|
string(api.ResourceServices),
|
||||||
string(ResourceReplicationControllers),
|
string(api.ResourceReplicationControllers),
|
||||||
string(ResourceSecrets),
|
string(api.ResourceSecrets),
|
||||||
string(ResourceConfigMaps),
|
string(api.ResourceConfigMaps),
|
||||||
string(ResourcePersistentVolumeClaims),
|
string(api.ResourcePersistentVolumeClaims),
|
||||||
string(ResourceStorage),
|
string(api.ResourceStorage),
|
||||||
string(ResourceRequestsStorage),
|
string(api.ResourceRequestsStorage),
|
||||||
)
|
)
|
||||||
|
|
||||||
// IsStandardResourceName returns true if the resource is known to the system
|
// IsStandardResourceName returns true if the resource is known to the system
|
||||||
@ -212,50 +191,50 @@ func IsStandardResourceName(str string) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var integerResources = sets.NewString(
|
var integerResources = sets.NewString(
|
||||||
string(ResourcePods),
|
string(api.ResourcePods),
|
||||||
string(ResourceQuotas),
|
string(api.ResourceQuotas),
|
||||||
string(ResourceServices),
|
string(api.ResourceServices),
|
||||||
string(ResourceReplicationControllers),
|
string(api.ResourceReplicationControllers),
|
||||||
string(ResourceSecrets),
|
string(api.ResourceSecrets),
|
||||||
string(ResourceConfigMaps),
|
string(api.ResourceConfigMaps),
|
||||||
string(ResourcePersistentVolumeClaims),
|
string(api.ResourcePersistentVolumeClaims),
|
||||||
string(ResourceServicesNodePorts),
|
string(api.ResourceServicesNodePorts),
|
||||||
string(ResourceServicesLoadBalancers),
|
string(api.ResourceServicesLoadBalancers),
|
||||||
)
|
)
|
||||||
|
|
||||||
// IsIntegerResourceName returns true if the resource is measured in integer values
|
// IsIntegerResourceName returns true if the resource is measured in integer values
|
||||||
func IsIntegerResourceName(str string) bool {
|
func IsIntegerResourceName(str string) bool {
|
||||||
return integerResources.Has(str) || IsOpaqueIntResourceName(ResourceName(str))
|
return integerResources.Has(str) || IsOpaqueIntResourceName(api.ResourceName(str))
|
||||||
}
|
}
|
||||||
|
|
||||||
// this function aims to check if the service's ClusterIP is set or not
|
// this function aims to check if the service's ClusterIP is set or not
|
||||||
// the objective is not to perform validation here
|
// the objective is not to perform validation here
|
||||||
func IsServiceIPSet(service *Service) bool {
|
func IsServiceIPSet(service *api.Service) bool {
|
||||||
return service.Spec.ClusterIP != ClusterIPNone && service.Spec.ClusterIP != ""
|
return service.Spec.ClusterIP != api.ClusterIPNone && service.Spec.ClusterIP != ""
|
||||||
}
|
}
|
||||||
|
|
||||||
// this function aims to check if the service's cluster IP is requested or not
|
// this function aims to check if the service's cluster IP is requested or not
|
||||||
func IsServiceIPRequested(service *Service) bool {
|
func IsServiceIPRequested(service *api.Service) bool {
|
||||||
// ExternalName services are CNAME aliases to external ones. Ignore the IP.
|
// ExternalName services are CNAME aliases to external ones. Ignore the IP.
|
||||||
if service.Spec.Type == ServiceTypeExternalName {
|
if service.Spec.Type == api.ServiceTypeExternalName {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return service.Spec.ClusterIP == ""
|
return service.Spec.ClusterIP == ""
|
||||||
}
|
}
|
||||||
|
|
||||||
var standardFinalizers = sets.NewString(
|
var standardFinalizers = sets.NewString(
|
||||||
string(FinalizerKubernetes),
|
string(api.FinalizerKubernetes),
|
||||||
metav1.FinalizerOrphanDependents,
|
metav1.FinalizerOrphanDependents,
|
||||||
)
|
)
|
||||||
|
|
||||||
// HasAnnotation returns a bool if passed in annotation exists
|
// HasAnnotation returns a bool if passed in annotation exists
|
||||||
func HasAnnotation(obj ObjectMeta, ann string) bool {
|
func HasAnnotation(obj api.ObjectMeta, ann string) bool {
|
||||||
_, found := obj.Annotations[ann]
|
_, found := obj.Annotations[ann]
|
||||||
return found
|
return found
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetMetaDataAnnotation sets the annotation and value
|
// SetMetaDataAnnotation sets the annotation and value
|
||||||
func SetMetaDataAnnotation(obj *ObjectMeta, ann string, value string) {
|
func SetMetaDataAnnotation(obj *api.ObjectMeta, ann string, value string) {
|
||||||
if obj.Annotations == nil {
|
if obj.Annotations == nil {
|
||||||
obj.Annotations = make(map[string]string)
|
obj.Annotations = make(map[string]string)
|
||||||
}
|
}
|
||||||
@ -268,7 +247,7 @@ func IsStandardFinalizerName(str string) bool {
|
|||||||
|
|
||||||
// AddToNodeAddresses appends the NodeAddresses to the passed-by-pointer slice,
|
// AddToNodeAddresses appends the NodeAddresses to the passed-by-pointer slice,
|
||||||
// only if they do not already exist
|
// only if they do not already exist
|
||||||
func AddToNodeAddresses(addresses *[]NodeAddress, addAddresses ...NodeAddress) {
|
func AddToNodeAddresses(addresses *[]api.NodeAddress, addAddresses ...api.NodeAddress) {
|
||||||
for _, add := range addAddresses {
|
for _, add := range addAddresses {
|
||||||
exists := false
|
exists := false
|
||||||
for _, existing := range *addresses {
|
for _, existing := range *addresses {
|
||||||
@ -292,11 +271,11 @@ func HashObject(obj runtime.Object, codec runtime.Codec) (string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: make method on LoadBalancerStatus?
|
// TODO: make method on LoadBalancerStatus?
|
||||||
func LoadBalancerStatusEqual(l, r *LoadBalancerStatus) bool {
|
func LoadBalancerStatusEqual(l, r *api.LoadBalancerStatus) bool {
|
||||||
return ingressSliceEqual(l.Ingress, r.Ingress)
|
return ingressSliceEqual(l.Ingress, r.Ingress)
|
||||||
}
|
}
|
||||||
|
|
||||||
func ingressSliceEqual(lhs, rhs []LoadBalancerIngress) bool {
|
func ingressSliceEqual(lhs, rhs []api.LoadBalancerIngress) bool {
|
||||||
if len(lhs) != len(rhs) {
|
if len(lhs) != len(rhs) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@ -308,7 +287,7 @@ func ingressSliceEqual(lhs, rhs []LoadBalancerIngress) bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func ingressEqual(lhs, rhs *LoadBalancerIngress) bool {
|
func ingressEqual(lhs, rhs *api.LoadBalancerIngress) bool {
|
||||||
if lhs.IP != rhs.IP {
|
if lhs.IP != rhs.IP {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@ -319,9 +298,9 @@ func ingressEqual(lhs, rhs *LoadBalancerIngress) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: make method on LoadBalancerStatus?
|
// TODO: make method on LoadBalancerStatus?
|
||||||
func LoadBalancerStatusDeepCopy(lb *LoadBalancerStatus) *LoadBalancerStatus {
|
func LoadBalancerStatusDeepCopy(lb *api.LoadBalancerStatus) *api.LoadBalancerStatus {
|
||||||
c := &LoadBalancerStatus{}
|
c := &api.LoadBalancerStatus{}
|
||||||
c.Ingress = make([]LoadBalancerIngress, len(lb.Ingress))
|
c.Ingress = make([]api.LoadBalancerIngress, len(lb.Ingress))
|
||||||
for i := range lb.Ingress {
|
for i := range lb.Ingress {
|
||||||
c.Ingress[i] = lb.Ingress[i]
|
c.Ingress[i] = lb.Ingress[i]
|
||||||
}
|
}
|
||||||
@ -330,42 +309,42 @@ func LoadBalancerStatusDeepCopy(lb *LoadBalancerStatus) *LoadBalancerStatus {
|
|||||||
|
|
||||||
// GetAccessModesAsString returns a string representation of an array of access modes.
|
// GetAccessModesAsString returns a string representation of an array of access modes.
|
||||||
// modes, when present, are always in the same order: RWO,ROX,RWX.
|
// modes, when present, are always in the same order: RWO,ROX,RWX.
|
||||||
func GetAccessModesAsString(modes []PersistentVolumeAccessMode) string {
|
func GetAccessModesAsString(modes []api.PersistentVolumeAccessMode) string {
|
||||||
modes = removeDuplicateAccessModes(modes)
|
modes = removeDuplicateAccessModes(modes)
|
||||||
modesStr := []string{}
|
modesStr := []string{}
|
||||||
if containsAccessMode(modes, ReadWriteOnce) {
|
if containsAccessMode(modes, api.ReadWriteOnce) {
|
||||||
modesStr = append(modesStr, "RWO")
|
modesStr = append(modesStr, "RWO")
|
||||||
}
|
}
|
||||||
if containsAccessMode(modes, ReadOnlyMany) {
|
if containsAccessMode(modes, api.ReadOnlyMany) {
|
||||||
modesStr = append(modesStr, "ROX")
|
modesStr = append(modesStr, "ROX")
|
||||||
}
|
}
|
||||||
if containsAccessMode(modes, ReadWriteMany) {
|
if containsAccessMode(modes, api.ReadWriteMany) {
|
||||||
modesStr = append(modesStr, "RWX")
|
modesStr = append(modesStr, "RWX")
|
||||||
}
|
}
|
||||||
return strings.Join(modesStr, ",")
|
return strings.Join(modesStr, ",")
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetAccessModesAsString returns an array of AccessModes from a string created by GetAccessModesAsString
|
// GetAccessModesAsString returns an array of AccessModes from a string created by GetAccessModesAsString
|
||||||
func GetAccessModesFromString(modes string) []PersistentVolumeAccessMode {
|
func GetAccessModesFromString(modes string) []api.PersistentVolumeAccessMode {
|
||||||
strmodes := strings.Split(modes, ",")
|
strmodes := strings.Split(modes, ",")
|
||||||
accessModes := []PersistentVolumeAccessMode{}
|
accessModes := []api.PersistentVolumeAccessMode{}
|
||||||
for _, s := range strmodes {
|
for _, s := range strmodes {
|
||||||
s = strings.Trim(s, " ")
|
s = strings.Trim(s, " ")
|
||||||
switch {
|
switch {
|
||||||
case s == "RWO":
|
case s == "RWO":
|
||||||
accessModes = append(accessModes, ReadWriteOnce)
|
accessModes = append(accessModes, api.ReadWriteOnce)
|
||||||
case s == "ROX":
|
case s == "ROX":
|
||||||
accessModes = append(accessModes, ReadOnlyMany)
|
accessModes = append(accessModes, api.ReadOnlyMany)
|
||||||
case s == "RWX":
|
case s == "RWX":
|
||||||
accessModes = append(accessModes, ReadWriteMany)
|
accessModes = append(accessModes, api.ReadWriteMany)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return accessModes
|
return accessModes
|
||||||
}
|
}
|
||||||
|
|
||||||
// removeDuplicateAccessModes returns an array of access modes without any duplicates
|
// removeDuplicateAccessModes returns an array of access modes without any duplicates
|
||||||
func removeDuplicateAccessModes(modes []PersistentVolumeAccessMode) []PersistentVolumeAccessMode {
|
func removeDuplicateAccessModes(modes []api.PersistentVolumeAccessMode) []api.PersistentVolumeAccessMode {
|
||||||
accessModes := []PersistentVolumeAccessMode{}
|
accessModes := []api.PersistentVolumeAccessMode{}
|
||||||
for _, m := range modes {
|
for _, m := range modes {
|
||||||
if !containsAccessMode(accessModes, m) {
|
if !containsAccessMode(accessModes, m) {
|
||||||
accessModes = append(accessModes, m)
|
accessModes = append(accessModes, m)
|
||||||
@ -374,7 +353,7 @@ func removeDuplicateAccessModes(modes []PersistentVolumeAccessMode) []Persistent
|
|||||||
return accessModes
|
return accessModes
|
||||||
}
|
}
|
||||||
|
|
||||||
func containsAccessMode(modes []PersistentVolumeAccessMode, mode PersistentVolumeAccessMode) bool {
|
func containsAccessMode(modes []api.PersistentVolumeAccessMode, mode api.PersistentVolumeAccessMode) bool {
|
||||||
for _, m := range modes {
|
for _, m := range modes {
|
||||||
if m == mode {
|
if m == mode {
|
||||||
return true
|
return true
|
||||||
@ -397,7 +376,7 @@ func ParseRFC3339(s string, nowFn func() metav1.Time) (metav1.Time, error) {
|
|||||||
|
|
||||||
// NodeSelectorRequirementsAsSelector converts the []NodeSelectorRequirement api type into a struct that implements
|
// NodeSelectorRequirementsAsSelector converts the []NodeSelectorRequirement api type into a struct that implements
|
||||||
// labels.Selector.
|
// labels.Selector.
|
||||||
func NodeSelectorRequirementsAsSelector(nsm []NodeSelectorRequirement) (labels.Selector, error) {
|
func NodeSelectorRequirementsAsSelector(nsm []api.NodeSelectorRequirement) (labels.Selector, error) {
|
||||||
if len(nsm) == 0 {
|
if len(nsm) == 0 {
|
||||||
return labels.Nothing(), nil
|
return labels.Nothing(), nil
|
||||||
}
|
}
|
||||||
@ -405,17 +384,17 @@ func NodeSelectorRequirementsAsSelector(nsm []NodeSelectorRequirement) (labels.S
|
|||||||
for _, expr := range nsm {
|
for _, expr := range nsm {
|
||||||
var op selection.Operator
|
var op selection.Operator
|
||||||
switch expr.Operator {
|
switch expr.Operator {
|
||||||
case NodeSelectorOpIn:
|
case api.NodeSelectorOpIn:
|
||||||
op = selection.In
|
op = selection.In
|
||||||
case NodeSelectorOpNotIn:
|
case api.NodeSelectorOpNotIn:
|
||||||
op = selection.NotIn
|
op = selection.NotIn
|
||||||
case NodeSelectorOpExists:
|
case api.NodeSelectorOpExists:
|
||||||
op = selection.Exists
|
op = selection.Exists
|
||||||
case NodeSelectorOpDoesNotExist:
|
case api.NodeSelectorOpDoesNotExist:
|
||||||
op = selection.DoesNotExist
|
op = selection.DoesNotExist
|
||||||
case NodeSelectorOpGt:
|
case api.NodeSelectorOpGt:
|
||||||
op = selection.GreaterThan
|
op = selection.GreaterThan
|
||||||
case NodeSelectorOpLt:
|
case api.NodeSelectorOpLt:
|
||||||
op = selection.LessThan
|
op = selection.LessThan
|
||||||
default:
|
default:
|
||||||
return nil, fmt.Errorf("%q is not a valid node selector operator", expr.Operator)
|
return nil, fmt.Errorf("%q is not a valid node selector operator", expr.Operator)
|
||||||
@ -431,10 +410,10 @@ func NodeSelectorRequirementsAsSelector(nsm []NodeSelectorRequirement) (labels.S
|
|||||||
|
|
||||||
// GetTolerationsFromPodAnnotations gets the json serialized tolerations data from Pod.Annotations
|
// GetTolerationsFromPodAnnotations gets the json serialized tolerations data from Pod.Annotations
|
||||||
// and converts it to the []Toleration type in api.
|
// and converts it to the []Toleration type in api.
|
||||||
func GetTolerationsFromPodAnnotations(annotations map[string]string) ([]Toleration, error) {
|
func GetTolerationsFromPodAnnotations(annotations map[string]string) ([]api.Toleration, error) {
|
||||||
var tolerations []Toleration
|
var tolerations []api.Toleration
|
||||||
if len(annotations) > 0 && annotations[TolerationsAnnotationKey] != "" {
|
if len(annotations) > 0 && annotations[api.TolerationsAnnotationKey] != "" {
|
||||||
err := json.Unmarshal([]byte(annotations[TolerationsAnnotationKey]), &tolerations)
|
err := json.Unmarshal([]byte(annotations[api.TolerationsAnnotationKey]), &tolerations)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return tolerations, err
|
return tolerations, err
|
||||||
}
|
}
|
||||||
@ -444,10 +423,10 @@ func GetTolerationsFromPodAnnotations(annotations map[string]string) ([]Tolerati
|
|||||||
|
|
||||||
// AddOrUpdateTolerationInPod tries to add a toleration to the pod's toleration list.
|
// AddOrUpdateTolerationInPod tries to add a toleration to the pod's toleration list.
|
||||||
// Returns true if something was updated, false otherwise.
|
// Returns true if something was updated, false otherwise.
|
||||||
func AddOrUpdateTolerationInPod(pod *Pod, toleration *Toleration) bool {
|
func AddOrUpdateTolerationInPod(pod *api.Pod, toleration *api.Toleration) bool {
|
||||||
podTolerations := pod.Spec.Tolerations
|
podTolerations := pod.Spec.Tolerations
|
||||||
|
|
||||||
var newTolerations []Toleration
|
var newTolerations []api.Toleration
|
||||||
updated := false
|
updated := false
|
||||||
for i := range podTolerations {
|
for i := range podTolerations {
|
||||||
if toleration.MatchToleration(&podTolerations[i]) {
|
if toleration.MatchToleration(&podTolerations[i]) {
|
||||||
@ -470,18 +449,8 @@ func AddOrUpdateTolerationInPod(pod *Pod, toleration *Toleration) bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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
|
|
||||||
}
|
|
||||||
|
|
||||||
// TolerationToleratesTaint checks if the toleration tolerates the taint.
|
// TolerationToleratesTaint checks if the toleration tolerates the taint.
|
||||||
func TolerationToleratesTaint(toleration *Toleration, taint *Taint) bool {
|
func TolerationToleratesTaint(toleration *api.Toleration, taint *api.Taint) bool {
|
||||||
if len(toleration.Effect) != 0 && toleration.Effect != taint.Effect {
|
if len(toleration.Effect) != 0 && toleration.Effect != taint.Effect {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@ -490,17 +459,17 @@ func TolerationToleratesTaint(toleration *Toleration, taint *Taint) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
// TODO: Use proper defaulting when Toleration becomes a field of PodSpec
|
// TODO: Use proper defaulting when Toleration becomes a field of PodSpec
|
||||||
if (len(toleration.Operator) == 0 || toleration.Operator == TolerationOpEqual) && toleration.Value == taint.Value {
|
if (len(toleration.Operator) == 0 || toleration.Operator == api.TolerationOpEqual) && toleration.Value == taint.Value {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if toleration.Operator == TolerationOpExists {
|
if toleration.Operator == api.TolerationOpExists {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// TaintToleratedByTolerations checks if taint is tolerated by any of the tolerations.
|
// TaintToleratedByTolerations checks if taint is tolerated by any of the tolerations.
|
||||||
func TaintToleratedByTolerations(taint *Taint, tolerations []Toleration) bool {
|
func TaintToleratedByTolerations(taint *api.Taint, tolerations []api.Toleration) bool {
|
||||||
tolerated := false
|
tolerated := false
|
||||||
for i := range tolerations {
|
for i := range tolerations {
|
||||||
if TolerationToleratesTaint(&tolerations[i], taint) {
|
if TolerationToleratesTaint(&tolerations[i], taint) {
|
||||||
@ -511,28 +480,14 @@ func TaintToleratedByTolerations(taint *Taint, tolerations []Toleration) bool {
|
|||||||
return tolerated
|
return tolerated
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetTaintsFromNodeAnnotations gets the json serialized taints data from Pod.Annotations
|
// GetTaintsFromNodeAnnotations gets the json serialized taints data from Pod.Annotations
|
||||||
// and converts it to the []Taint type in api.
|
// and converts it to the []Taint type in api.
|
||||||
func GetTaintsFromNodeAnnotations(annotations map[string]string) ([]Taint, error) {
|
func GetTaintsFromNodeAnnotations(annotations map[string]string) ([]api.Taint, error) {
|
||||||
var taints []Taint
|
var taints []api.Taint
|
||||||
if len(annotations) > 0 && annotations[TaintsAnnotationKey] != "" {
|
if len(annotations) > 0 && annotations[api.TaintsAnnotationKey] != "" {
|
||||||
err := json.Unmarshal([]byte(annotations[TaintsAnnotationKey]), &taints)
|
err := json.Unmarshal([]byte(annotations[api.TaintsAnnotationKey]), &taints)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return []Taint{}, err
|
return []api.Taint{}, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return taints, nil
|
return taints, nil
|
||||||
@ -541,12 +496,12 @@ func GetTaintsFromNodeAnnotations(annotations map[string]string) ([]Taint, error
|
|||||||
// SysctlsFromPodAnnotations parses the sysctl annotations into a slice of safe Sysctls
|
// SysctlsFromPodAnnotations parses the sysctl annotations into a slice of safe Sysctls
|
||||||
// and a slice of unsafe Sysctls. This is only a convenience wrapper around
|
// and a slice of unsafe Sysctls. This is only a convenience wrapper around
|
||||||
// SysctlsFromPodAnnotation.
|
// SysctlsFromPodAnnotation.
|
||||||
func SysctlsFromPodAnnotations(a map[string]string) ([]Sysctl, []Sysctl, error) {
|
func SysctlsFromPodAnnotations(a map[string]string) ([]api.Sysctl, []api.Sysctl, error) {
|
||||||
safe, err := SysctlsFromPodAnnotation(a[SysctlsPodAnnotationKey])
|
safe, err := SysctlsFromPodAnnotation(a[api.SysctlsPodAnnotationKey])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
unsafe, err := SysctlsFromPodAnnotation(a[UnsafeSysctlsPodAnnotationKey])
|
unsafe, err := SysctlsFromPodAnnotation(a[api.UnsafeSysctlsPodAnnotationKey])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
@ -555,13 +510,13 @@ func SysctlsFromPodAnnotations(a map[string]string) ([]Sysctl, []Sysctl, error)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SysctlsFromPodAnnotation parses an annotation value into a slice of Sysctls.
|
// SysctlsFromPodAnnotation parses an annotation value into a slice of Sysctls.
|
||||||
func SysctlsFromPodAnnotation(annotation string) ([]Sysctl, error) {
|
func SysctlsFromPodAnnotation(annotation string) ([]api.Sysctl, error) {
|
||||||
if len(annotation) == 0 {
|
if len(annotation) == 0 {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
kvs := strings.Split(annotation, ",")
|
kvs := strings.Split(annotation, ",")
|
||||||
sysctls := make([]Sysctl, len(kvs))
|
sysctls := make([]api.Sysctl, len(kvs))
|
||||||
for i, kv := range kvs {
|
for i, kv := range kvs {
|
||||||
cs := strings.Split(kv, "=")
|
cs := strings.Split(kv, "=")
|
||||||
if len(cs) != 2 || len(cs[0]) == 0 {
|
if len(cs) != 2 || len(cs[0]) == 0 {
|
||||||
@ -574,7 +529,7 @@ func SysctlsFromPodAnnotation(annotation string) ([]Sysctl, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// PodAnnotationsFromSysctls creates an annotation value for a slice of Sysctls.
|
// PodAnnotationsFromSysctls creates an annotation value for a slice of Sysctls.
|
||||||
func PodAnnotationsFromSysctls(sysctls []Sysctl) string {
|
func PodAnnotationsFromSysctls(sysctls []api.Sysctl) string {
|
||||||
if len(sysctls) == 0 {
|
if len(sysctls) == 0 {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
@ -589,10 +544,10 @@ func PodAnnotationsFromSysctls(sysctls []Sysctl) string {
|
|||||||
// GetAffinityFromPodAnnotations gets the json serialized affinity data from Pod.Annotations
|
// GetAffinityFromPodAnnotations gets the json serialized affinity data from Pod.Annotations
|
||||||
// and converts it to the Affinity type in api.
|
// and converts it to the Affinity type in api.
|
||||||
// TODO: remove when alpha support for affinity is removed
|
// TODO: remove when alpha support for affinity is removed
|
||||||
func GetAffinityFromPodAnnotations(annotations map[string]string) (*Affinity, error) {
|
func GetAffinityFromPodAnnotations(annotations map[string]string) (*api.Affinity, error) {
|
||||||
if len(annotations) > 0 && annotations[AffinityAnnotationKey] != "" {
|
if len(annotations) > 0 && annotations[api.AffinityAnnotationKey] != "" {
|
||||||
var affinity Affinity
|
var affinity api.Affinity
|
||||||
err := json.Unmarshal([]byte(annotations[AffinityAnnotationKey]), &affinity)
|
err := json.Unmarshal([]byte(annotations[api.AffinityAnnotationKey]), &affinity)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -602,9 +557,9 @@ func GetAffinityFromPodAnnotations(annotations map[string]string) (*Affinity, er
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetPersistentVolumeClass returns StorageClassName.
|
// GetPersistentVolumeClass returns StorageClassName.
|
||||||
func GetPersistentVolumeClass(volume *PersistentVolume) string {
|
func GetPersistentVolumeClass(volume *api.PersistentVolume) string {
|
||||||
// Use beta annotation first
|
// Use beta annotation first
|
||||||
if class, found := volume.Annotations[BetaStorageClassAnnotation]; found {
|
if class, found := volume.Annotations[api.BetaStorageClassAnnotation]; found {
|
||||||
return class
|
return class
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -613,9 +568,9 @@ func GetPersistentVolumeClass(volume *PersistentVolume) string {
|
|||||||
|
|
||||||
// GetPersistentVolumeClaimClass returns StorageClassName. If no storage class was
|
// GetPersistentVolumeClaimClass returns StorageClassName. If no storage class was
|
||||||
// requested, it returns "".
|
// requested, it returns "".
|
||||||
func GetPersistentVolumeClaimClass(claim *PersistentVolumeClaim) string {
|
func GetPersistentVolumeClaimClass(claim *api.PersistentVolumeClaim) string {
|
||||||
// Use beta annotation first
|
// Use beta annotation first
|
||||||
if class, found := claim.Annotations[BetaStorageClassAnnotation]; found {
|
if class, found := claim.Annotations[api.BetaStorageClassAnnotation]; found {
|
||||||
return class
|
return class
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -627,9 +582,9 @@ func GetPersistentVolumeClaimClass(claim *PersistentVolumeClaim) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// PersistentVolumeClaimHasClass returns true if given claim has set StorageClassName field.
|
// PersistentVolumeClaimHasClass returns true if given claim has set StorageClassName field.
|
||||||
func PersistentVolumeClaimHasClass(claim *PersistentVolumeClaim) bool {
|
func PersistentVolumeClaimHasClass(claim *api.PersistentVolumeClaim) bool {
|
||||||
// Use beta annotation first
|
// Use beta annotation first
|
||||||
if _, found := claim.Annotations[BetaStorageClassAnnotation]; found {
|
if _, found := claim.Annotations[api.BetaStorageClassAnnotation]; found {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
268
pkg/api/helper/helpers_test.go
Normal file
268
pkg/api/helper/helpers_test.go
Normal file
@ -0,0 +1,268 @@
|
|||||||
|
/*
|
||||||
|
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},
|
||||||
|
}
|
||||||
|
for i, tc := range testCases {
|
||||||
|
if IsStandardResourceName(tc.input) != tc.output {
|
||||||
|
t.Errorf("case[%d], expected: %t, got: %t", i, 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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,389 +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
|
|
||||||
|
|
||||||
import (
|
|
||||||
"reflect"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"k8s.io/apimachinery/pkg/api/resource"
|
|
||||||
"k8s.io/apimachinery/pkg/labels"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestConversionError(t *testing.T) {
|
|
||||||
var i int
|
|
||||||
var s string
|
|
||||||
i = 3
|
|
||||||
s = "foo"
|
|
||||||
c := ConversionError{
|
|
||||||
In: &i, Out: &s,
|
|
||||||
Message: "Can't make x into y, silly",
|
|
||||||
}
|
|
||||||
var e error
|
|
||||||
e = &c // ensure it implements error
|
|
||||||
msg := e.Error()
|
|
||||||
t.Logf("Message is %v", msg)
|
|
||||||
for _, part := range []string{"3", "int", "string", "Can't"} {
|
|
||||||
if !strings.Contains(msg, part) {
|
|
||||||
t.Errorf("didn't find %v", part)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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},
|
|
||||||
}
|
|
||||||
for i, tc := range testCases {
|
|
||||||
if IsStandardResourceName(tc.input) != tc.output {
|
|
||||||
t.Errorf("case[%d], expected: %t, got: %t", i, tc.output, !tc.output)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestAddToNodeAddresses(t *testing.T) {
|
|
||||||
testCases := []struct {
|
|
||||||
existing []NodeAddress
|
|
||||||
toAdd []NodeAddress
|
|
||||||
expected []NodeAddress
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
existing: []NodeAddress{},
|
|
||||||
toAdd: []NodeAddress{},
|
|
||||||
expected: []NodeAddress{},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
existing: []NodeAddress{},
|
|
||||||
toAdd: []NodeAddress{
|
|
||||||
{Type: NodeExternalIP, Address: "1.1.1.1"},
|
|
||||||
{Type: NodeHostName, Address: "localhost"},
|
|
||||||
},
|
|
||||||
expected: []NodeAddress{
|
|
||||||
{Type: NodeExternalIP, Address: "1.1.1.1"},
|
|
||||||
{Type: NodeHostName, Address: "localhost"},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
existing: []NodeAddress{},
|
|
||||||
toAdd: []NodeAddress{
|
|
||||||
{Type: NodeExternalIP, Address: "1.1.1.1"},
|
|
||||||
{Type: NodeExternalIP, Address: "1.1.1.1"},
|
|
||||||
},
|
|
||||||
expected: []NodeAddress{
|
|
||||||
{Type: NodeExternalIP, Address: "1.1.1.1"},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
existing: []NodeAddress{
|
|
||||||
{Type: NodeExternalIP, Address: "1.1.1.1"},
|
|
||||||
{Type: NodeInternalIP, Address: "10.1.1.1"},
|
|
||||||
},
|
|
||||||
toAdd: []NodeAddress{
|
|
||||||
{Type: NodeExternalIP, Address: "1.1.1.1"},
|
|
||||||
{Type: NodeHostName, Address: "localhost"},
|
|
||||||
},
|
|
||||||
expected: []NodeAddress{
|
|
||||||
{Type: NodeExternalIP, Address: "1.1.1.1"},
|
|
||||||
{Type: NodeInternalIP, Address: "10.1.1.1"},
|
|
||||||
{Type: 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, ReadOnlyMany) {
|
|
||||||
t.Errorf("Expected mode %s, but got %+v", ReadOnlyMany, modes)
|
|
||||||
}
|
|
||||||
|
|
||||||
modes = GetAccessModesFromString("ROX,RWX")
|
|
||||||
if !containsAccessMode(modes, ReadOnlyMany) {
|
|
||||||
t.Errorf("Expected mode %s, but got %+v", ReadOnlyMany, modes)
|
|
||||||
}
|
|
||||||
if !containsAccessMode(modes, ReadWriteMany) {
|
|
||||||
t.Errorf("Expected mode %s, but got %+v", ReadWriteMany, modes)
|
|
||||||
}
|
|
||||||
|
|
||||||
modes = GetAccessModesFromString("RWO,ROX,RWX")
|
|
||||||
if !containsAccessMode(modes, ReadOnlyMany) {
|
|
||||||
t.Errorf("Expected mode %s, but got %+v", ReadOnlyMany, modes)
|
|
||||||
}
|
|
||||||
if !containsAccessMode(modes, ReadWriteMany) {
|
|
||||||
t.Errorf("Expected mode %s, but got %+v", ReadWriteMany, modes)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestRemoveDuplicateAccessModes(t *testing.T) {
|
|
||||||
modes := []PersistentVolumeAccessMode{
|
|
||||||
ReadWriteOnce, ReadOnlyMany, ReadOnlyMany, 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 := []NodeSelectorRequirement{{
|
|
||||||
Key: "foo",
|
|
||||||
Operator: 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 []NodeSelectorRequirement
|
|
||||||
out labels.Selector
|
|
||||||
expectErr bool
|
|
||||||
}{
|
|
||||||
{in: nil, out: labels.Nothing()},
|
|
||||||
{in: []NodeSelectorRequirement{}, out: labels.Nothing()},
|
|
||||||
{
|
|
||||||
in: matchExpressions,
|
|
||||||
out: mustParse("foo in (baz,bar)"),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
in: []NodeSelectorRequirement{{
|
|
||||||
Key: "foo",
|
|
||||||
Operator: NodeSelectorOpExists,
|
|
||||||
Values: []string{"bar", "baz"},
|
|
||||||
}},
|
|
||||||
expectErr: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
in: []NodeSelectorRequirement{{
|
|
||||||
Key: "foo",
|
|
||||||
Operator: NodeSelectorOpGt,
|
|
||||||
Values: []string{"1"},
|
|
||||||
}},
|
|
||||||
out: mustParse("foo>1"),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
in: []NodeSelectorRequirement{{
|
|
||||||
Key: "bar",
|
|
||||||
Operator: 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 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())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestSysctlsFromPodAnnotation(t *testing.T) {
|
|
||||||
type Test struct {
|
|
||||||
annotation string
|
|
||||||
expectValue []Sysctl
|
|
||||||
expectErr bool
|
|
||||||
}
|
|
||||||
for i, test := range []Test{
|
|
||||||
{
|
|
||||||
annotation: "",
|
|
||||||
expectValue: nil,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
annotation: "foo.bar",
|
|
||||||
expectErr: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
annotation: "=123",
|
|
||||||
expectErr: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
annotation: "foo.bar=",
|
|
||||||
expectValue: []Sysctl{{Name: "foo.bar", Value: ""}},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
annotation: "foo.bar=42",
|
|
||||||
expectValue: []Sysctl{{Name: "foo.bar", Value: "42"}},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
annotation: "foo.bar=42,",
|
|
||||||
expectErr: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
annotation: "foo.bar=42,abc.def=1",
|
|
||||||
expectValue: []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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
46
pkg/api/methods.go
Normal file
46
pkg/api/methods.go
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
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"
|
||||||
|
|
||||||
|
// 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
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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
pkg/api/methods_test.go
Normal file
120
pkg/api/methods_test.go
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
/*
|
||||||
|
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())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -31,6 +31,7 @@ go_library(
|
|||||||
tags = ["automanaged"],
|
tags = ["automanaged"],
|
||||||
deps = [
|
deps = [
|
||||||
"//pkg/api:go_default_library",
|
"//pkg/api:go_default_library",
|
||||||
|
"//pkg/api/helper:go_default_library",
|
||||||
"//pkg/apis/extensions:go_default_library",
|
"//pkg/apis/extensions:go_default_library",
|
||||||
"//pkg/util:go_default_library",
|
"//pkg/util:go_default_library",
|
||||||
"//pkg/util/parsers:go_default_library",
|
"//pkg/util/parsers:go_default_library",
|
||||||
|
@ -28,6 +28,7 @@ import (
|
|||||||
"k8s.io/apimachinery/pkg/util/sets"
|
"k8s.io/apimachinery/pkg/util/sets"
|
||||||
|
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
|
"k8s.io/kubernetes/pkg/api/helper"
|
||||||
)
|
)
|
||||||
|
|
||||||
// IsOpaqueIntResourceName returns true if the resource name has the opaque
|
// IsOpaqueIntResourceName returns true if the resource name has the opaque
|
||||||
@ -285,7 +286,7 @@ func AddOrUpdateTolerationInPod(pod *Pod, toleration *Toleration) bool {
|
|||||||
updated := false
|
updated := false
|
||||||
for i := range podTolerations {
|
for i := range podTolerations {
|
||||||
if toleration.MatchToleration(&podTolerations[i]) {
|
if toleration.MatchToleration(&podTolerations[i]) {
|
||||||
if api.Semantic.DeepEqual(toleration, podTolerations[i]) {
|
if helper.Semantic.DeepEqual(toleration, podTolerations[i]) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
newTolerations = append(newTolerations, *toleration)
|
newTolerations = append(newTolerations, *toleration)
|
||||||
@ -527,7 +528,7 @@ func AddOrUpdateTaint(node *Node, taint *Taint) (*Node, bool, error) {
|
|||||||
updated := false
|
updated := false
|
||||||
for i := range nodeTaints {
|
for i := range nodeTaints {
|
||||||
if taint.MatchTaint(&nodeTaints[i]) {
|
if taint.MatchTaint(&nodeTaints[i]) {
|
||||||
if api.Semantic.DeepEqual(taint, nodeTaints[i]) {
|
if helper.Semantic.DeepEqual(taint, nodeTaints[i]) {
|
||||||
return newNode, false, nil
|
return newNode, false, nil
|
||||||
}
|
}
|
||||||
newTaints = append(newTaints, *taint)
|
newTaints = append(newTaints, *taint)
|
||||||
|
@ -12,7 +12,7 @@ go_library(
|
|||||||
srcs = ["validation.go"],
|
srcs = ["validation.go"],
|
||||||
tags = ["automanaged"],
|
tags = ["automanaged"],
|
||||||
deps = [
|
deps = [
|
||||||
"//pkg/api:go_default_library",
|
"//pkg/api/helper:go_default_library",
|
||||||
"//pkg/api/v1:go_default_library",
|
"//pkg/api/v1:go_default_library",
|
||||||
"//vendor:k8s.io/apimachinery/pkg/api/resource",
|
"//vendor:k8s.io/apimachinery/pkg/api/resource",
|
||||||
"//vendor:k8s.io/apimachinery/pkg/util/sets",
|
"//vendor:k8s.io/apimachinery/pkg/util/sets",
|
||||||
|
@ -24,7 +24,7 @@ import (
|
|||||||
"k8s.io/apimachinery/pkg/util/sets"
|
"k8s.io/apimachinery/pkg/util/sets"
|
||||||
"k8s.io/apimachinery/pkg/util/validation"
|
"k8s.io/apimachinery/pkg/util/validation"
|
||||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api/helper"
|
||||||
"k8s.io/kubernetes/pkg/api/v1"
|
"k8s.io/kubernetes/pkg/api/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -68,7 +68,7 @@ func ValidateResourceRequirements(requirements *v1.ResourceRequirements, fldPath
|
|||||||
func validateContainerResourceName(value string, fldPath *field.Path) field.ErrorList {
|
func validateContainerResourceName(value string, fldPath *field.Path) field.ErrorList {
|
||||||
allErrs := validateResourceName(value, fldPath)
|
allErrs := validateResourceName(value, fldPath)
|
||||||
if len(strings.Split(value, "/")) == 1 {
|
if len(strings.Split(value, "/")) == 1 {
|
||||||
if !api.IsStandardContainerResourceName(value) {
|
if !helper.IsStandardContainerResourceName(value) {
|
||||||
return append(allErrs, field.Invalid(fldPath, value, "must be a standard resource for containers"))
|
return append(allErrs, field.Invalid(fldPath, value, "must be a standard resource for containers"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -79,7 +79,7 @@ func validateContainerResourceName(value string, fldPath *field.Path) field.Erro
|
|||||||
func ValidateResourceQuantityValue(resource string, value resource.Quantity, fldPath *field.Path) field.ErrorList {
|
func ValidateResourceQuantityValue(resource string, value resource.Quantity, fldPath *field.Path) field.ErrorList {
|
||||||
allErrs := field.ErrorList{}
|
allErrs := field.ErrorList{}
|
||||||
allErrs = append(allErrs, ValidateNonnegativeQuantity(value, fldPath)...)
|
allErrs = append(allErrs, ValidateNonnegativeQuantity(value, fldPath)...)
|
||||||
if api.IsIntegerResourceName(resource) {
|
if helper.IsIntegerResourceName(resource) {
|
||||||
if value.MilliValue()%int64(1000) != int64(0) {
|
if value.MilliValue()%int64(1000) != int64(0) {
|
||||||
allErrs = append(allErrs, field.Invalid(fldPath, value, isNotIntegerErrorMsg))
|
allErrs = append(allErrs, field.Invalid(fldPath, value, isNotIntegerErrorMsg))
|
||||||
}
|
}
|
||||||
@ -108,7 +108,7 @@ func validateResourceName(value string, fldPath *field.Path) field.ErrorList {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if len(strings.Split(value, "/")) == 1 {
|
if len(strings.Split(value, "/")) == 1 {
|
||||||
if !api.IsStandardResourceName(value) {
|
if !helper.IsStandardResourceName(value) {
|
||||||
return append(allErrs, field.Invalid(fldPath, value, "must be a standard resource type or fully qualified"))
|
return append(allErrs, field.Invalid(fldPath, value, "must be a standard resource type or fully qualified"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@ go_library(
|
|||||||
tags = ["automanaged"],
|
tags = ["automanaged"],
|
||||||
deps = [
|
deps = [
|
||||||
"//pkg/api:go_default_library",
|
"//pkg/api:go_default_library",
|
||||||
|
"//pkg/api/helper:go_default_library",
|
||||||
"//pkg/api/service:go_default_library",
|
"//pkg/api/service:go_default_library",
|
||||||
"//pkg/api/util:go_default_library",
|
"//pkg/api/util:go_default_library",
|
||||||
"//pkg/api/v1:go_default_library",
|
"//pkg/api/v1:go_default_library",
|
||||||
@ -67,6 +68,7 @@ go_test(
|
|||||||
tags = ["automanaged"],
|
tags = ["automanaged"],
|
||||||
deps = [
|
deps = [
|
||||||
"//pkg/api:go_default_library",
|
"//pkg/api:go_default_library",
|
||||||
|
"//pkg/api/helper:go_default_library",
|
||||||
"//pkg/api/service:go_default_library",
|
"//pkg/api/service:go_default_library",
|
||||||
"//pkg/api/testapi:go_default_library",
|
"//pkg/api/testapi:go_default_library",
|
||||||
"//pkg/api/testing:go_default_library",
|
"//pkg/api/testing:go_default_library",
|
||||||
|
@ -41,6 +41,7 @@ import (
|
|||||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
|
"k8s.io/kubernetes/pkg/api/helper"
|
||||||
apiservice "k8s.io/kubernetes/pkg/api/service"
|
apiservice "k8s.io/kubernetes/pkg/api/service"
|
||||||
"k8s.io/kubernetes/pkg/api/v1"
|
"k8s.io/kubernetes/pkg/api/v1"
|
||||||
"k8s.io/kubernetes/pkg/capabilities"
|
"k8s.io/kubernetes/pkg/capabilities"
|
||||||
@ -115,13 +116,13 @@ func ValidatePodSpecificAnnotations(annotations map[string]string, spec *api.Pod
|
|||||||
allErrs = append(allErrs, ValidateSeccompPodAnnotations(annotations, fldPath)...)
|
allErrs = append(allErrs, ValidateSeccompPodAnnotations(annotations, fldPath)...)
|
||||||
allErrs = append(allErrs, ValidateAppArmorPodAnnotations(annotations, spec, fldPath)...)
|
allErrs = append(allErrs, ValidateAppArmorPodAnnotations(annotations, spec, fldPath)...)
|
||||||
|
|
||||||
sysctls, err := api.SysctlsFromPodAnnotation(annotations[api.SysctlsPodAnnotationKey])
|
sysctls, err := helper.SysctlsFromPodAnnotation(annotations[api.SysctlsPodAnnotationKey])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
allErrs = append(allErrs, field.Invalid(fldPath.Key(api.SysctlsPodAnnotationKey), annotations[api.SysctlsPodAnnotationKey], err.Error()))
|
allErrs = append(allErrs, field.Invalid(fldPath.Key(api.SysctlsPodAnnotationKey), annotations[api.SysctlsPodAnnotationKey], err.Error()))
|
||||||
} else {
|
} else {
|
||||||
allErrs = append(allErrs, validateSysctls(sysctls, fldPath.Key(api.SysctlsPodAnnotationKey))...)
|
allErrs = append(allErrs, validateSysctls(sysctls, fldPath.Key(api.SysctlsPodAnnotationKey))...)
|
||||||
}
|
}
|
||||||
unsafeSysctls, err := api.SysctlsFromPodAnnotation(annotations[api.UnsafeSysctlsPodAnnotationKey])
|
unsafeSysctls, err := helper.SysctlsFromPodAnnotation(annotations[api.UnsafeSysctlsPodAnnotationKey])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
allErrs = append(allErrs, field.Invalid(fldPath.Key(api.UnsafeSysctlsPodAnnotationKey), annotations[api.UnsafeSysctlsPodAnnotationKey], err.Error()))
|
allErrs = append(allErrs, field.Invalid(fldPath.Key(api.UnsafeSysctlsPodAnnotationKey), annotations[api.UnsafeSysctlsPodAnnotationKey], err.Error()))
|
||||||
} else {
|
} else {
|
||||||
@ -139,7 +140,7 @@ func ValidatePodSpecificAnnotations(annotations map[string]string, spec *api.Pod
|
|||||||
func ValidateTolerationsInPodAnnotations(annotations map[string]string, fldPath *field.Path) field.ErrorList {
|
func ValidateTolerationsInPodAnnotations(annotations map[string]string, fldPath *field.Path) field.ErrorList {
|
||||||
allErrs := field.ErrorList{}
|
allErrs := field.ErrorList{}
|
||||||
|
|
||||||
tolerations, err := api.GetTolerationsFromPodAnnotations(annotations)
|
tolerations, err := helper.GetTolerationsFromPodAnnotations(annotations)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
allErrs = append(allErrs, field.Invalid(fldPath, api.TolerationsAnnotationKey, err.Error()))
|
allErrs = append(allErrs, field.Invalid(fldPath, api.TolerationsAnnotationKey, err.Error()))
|
||||||
return allErrs
|
return allErrs
|
||||||
@ -156,7 +157,7 @@ func ValidateTolerationsInPodAnnotations(annotations map[string]string, fldPath
|
|||||||
func ValidateAffinityInPodAnnotations(annotations map[string]string, fldPath *field.Path) field.ErrorList {
|
func ValidateAffinityInPodAnnotations(annotations map[string]string, fldPath *field.Path) field.ErrorList {
|
||||||
allErrs := field.ErrorList{}
|
allErrs := field.ErrorList{}
|
||||||
|
|
||||||
affinity, err := api.GetAffinityFromPodAnnotations(annotations)
|
affinity, err := helper.GetAffinityFromPodAnnotations(annotations)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
allErrs = append(allErrs, field.Invalid(fldPath, api.AffinityAnnotationKey, err.Error()))
|
allErrs = append(allErrs, field.Invalid(fldPath, api.AffinityAnnotationKey, err.Error()))
|
||||||
return allErrs
|
return allErrs
|
||||||
@ -2625,7 +2626,7 @@ func validateServiceFields(service *api.Service) field.ErrorList {
|
|||||||
allErrs = append(allErrs, field.NotSupported(specPath.Child("sessionAffinity"), service.Spec.SessionAffinity, supportedSessionAffinityType.List()))
|
allErrs = append(allErrs, field.NotSupported(specPath.Child("sessionAffinity"), service.Spec.SessionAffinity, supportedSessionAffinityType.List()))
|
||||||
}
|
}
|
||||||
|
|
||||||
if api.IsServiceIPSet(service) {
|
if helper.IsServiceIPSet(service) {
|
||||||
if ip := net.ParseIP(service.Spec.ClusterIP); ip == nil {
|
if ip := net.ParseIP(service.Spec.ClusterIP); ip == nil {
|
||||||
allErrs = append(allErrs, field.Invalid(specPath.Child("clusterIP"), service.Spec.ClusterIP, "must be empty, 'None', or a valid IP address"))
|
allErrs = append(allErrs, field.Invalid(specPath.Child("clusterIP"), service.Spec.ClusterIP, "must be empty, 'None', or a valid IP address"))
|
||||||
}
|
}
|
||||||
@ -2958,7 +2959,7 @@ func ValidateReadOnlyPersistentDisks(volumes []api.Volume, fldPath *field.Path)
|
|||||||
func ValidateTaintsInNodeAnnotations(annotations map[string]string, fldPath *field.Path) field.ErrorList {
|
func ValidateTaintsInNodeAnnotations(annotations map[string]string, fldPath *field.Path) field.ErrorList {
|
||||||
allErrs := field.ErrorList{}
|
allErrs := field.ErrorList{}
|
||||||
|
|
||||||
taints, err := api.GetTaintsFromNodeAnnotations(annotations)
|
taints, err := helper.GetTaintsFromNodeAnnotations(annotations)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
allErrs = append(allErrs, field.Invalid(fldPath, api.TaintsAnnotationKey, err.Error()))
|
allErrs = append(allErrs, field.Invalid(fldPath, api.TaintsAnnotationKey, err.Error()))
|
||||||
return allErrs
|
return allErrs
|
||||||
@ -3115,7 +3116,7 @@ func validateResourceName(value string, fldPath *field.Path) field.ErrorList {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if len(strings.Split(value, "/")) == 1 {
|
if len(strings.Split(value, "/")) == 1 {
|
||||||
if !api.IsStandardResourceName(value) {
|
if !helper.IsStandardResourceName(value) {
|
||||||
return append(allErrs, field.Invalid(fldPath, value, "must be a standard resource type or fully qualified"))
|
return append(allErrs, field.Invalid(fldPath, value, "must be a standard resource type or fully qualified"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3128,7 +3129,7 @@ func validateResourceName(value string, fldPath *field.Path) field.ErrorList {
|
|||||||
func validateContainerResourceName(value string, fldPath *field.Path) field.ErrorList {
|
func validateContainerResourceName(value string, fldPath *field.Path) field.ErrorList {
|
||||||
allErrs := validateResourceName(value, fldPath)
|
allErrs := validateResourceName(value, fldPath)
|
||||||
if len(strings.Split(value, "/")) == 1 {
|
if len(strings.Split(value, "/")) == 1 {
|
||||||
if !api.IsStandardContainerResourceName(value) {
|
if !helper.IsStandardContainerResourceName(value) {
|
||||||
return append(allErrs, field.Invalid(fldPath, value, "must be a standard resource for containers"))
|
return append(allErrs, field.Invalid(fldPath, value, "must be a standard resource for containers"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3140,7 +3141,7 @@ func validateContainerResourceName(value string, fldPath *field.Path) field.Erro
|
|||||||
func ValidateResourceQuotaResourceName(value string, fldPath *field.Path) field.ErrorList {
|
func ValidateResourceQuotaResourceName(value string, fldPath *field.Path) field.ErrorList {
|
||||||
allErrs := validateResourceName(value, fldPath)
|
allErrs := validateResourceName(value, fldPath)
|
||||||
if len(strings.Split(value, "/")) == 1 {
|
if len(strings.Split(value, "/")) == 1 {
|
||||||
if !api.IsStandardQuotaResourceName(value) {
|
if !helper.IsStandardQuotaResourceName(value) {
|
||||||
return append(allErrs, field.Invalid(fldPath, value, isInvalidQuotaResource))
|
return append(allErrs, field.Invalid(fldPath, value, isInvalidQuotaResource))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3158,7 +3159,7 @@ func validateLimitRangeTypeName(value string, fldPath *field.Path) field.ErrorLi
|
|||||||
}
|
}
|
||||||
|
|
||||||
if len(strings.Split(value, "/")) == 1 {
|
if len(strings.Split(value, "/")) == 1 {
|
||||||
if !api.IsStandardLimitRangeType(value) {
|
if !helper.IsStandardLimitRangeType(value) {
|
||||||
return append(allErrs, field.Invalid(fldPath, value, "must be a standard limit type or fully qualified"))
|
return append(allErrs, field.Invalid(fldPath, value, "must be a standard limit type or fully qualified"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3494,11 +3495,11 @@ func validateResourceQuotaScopes(resourceQuotaSpec *api.ResourceQuotaSpec, fld *
|
|||||||
fldPath := fld.Child("scopes")
|
fldPath := fld.Child("scopes")
|
||||||
scopeSet := sets.NewString()
|
scopeSet := sets.NewString()
|
||||||
for _, scope := range resourceQuotaSpec.Scopes {
|
for _, scope := range resourceQuotaSpec.Scopes {
|
||||||
if !api.IsStandardResourceQuotaScope(string(scope)) {
|
if !helper.IsStandardResourceQuotaScope(string(scope)) {
|
||||||
allErrs = append(allErrs, field.Invalid(fldPath, resourceQuotaSpec.Scopes, "unsupported scope"))
|
allErrs = append(allErrs, field.Invalid(fldPath, resourceQuotaSpec.Scopes, "unsupported scope"))
|
||||||
}
|
}
|
||||||
for _, k := range hardLimits.List() {
|
for _, k := range hardLimits.List() {
|
||||||
if api.IsStandardQuotaResourceName(k) && !api.IsResourceQuotaScopeValidForResource(scope, k) {
|
if helper.IsStandardQuotaResourceName(k) && !helper.IsResourceQuotaScopeValidForResource(scope, k) {
|
||||||
allErrs = append(allErrs, field.Invalid(fldPath, resourceQuotaSpec.Scopes, "unsupported scope applied to resource"))
|
allErrs = append(allErrs, field.Invalid(fldPath, resourceQuotaSpec.Scopes, "unsupported scope applied to resource"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3563,7 +3564,7 @@ func ValidateResourceQuotaSpec(resourceQuotaSpec *api.ResourceQuotaSpec, fld *fi
|
|||||||
func ValidateResourceQuantityValue(resource string, value resource.Quantity, fldPath *field.Path) field.ErrorList {
|
func ValidateResourceQuantityValue(resource string, value resource.Quantity, fldPath *field.Path) field.ErrorList {
|
||||||
allErrs := field.ErrorList{}
|
allErrs := field.ErrorList{}
|
||||||
allErrs = append(allErrs, ValidateNonnegativeQuantity(value, fldPath)...)
|
allErrs = append(allErrs, ValidateNonnegativeQuantity(value, fldPath)...)
|
||||||
if api.IsIntegerResourceName(resource) {
|
if helper.IsIntegerResourceName(resource) {
|
||||||
if value.MilliValue()%int64(1000) != int64(0) {
|
if value.MilliValue()%int64(1000) != int64(0) {
|
||||||
allErrs = append(allErrs, field.Invalid(fldPath, value, isNotIntegerErrorMsg))
|
allErrs = append(allErrs, field.Invalid(fldPath, value, isNotIntegerErrorMsg))
|
||||||
}
|
}
|
||||||
@ -3641,7 +3642,7 @@ func validateFinalizerName(stringValue string, fldPath *field.Path) field.ErrorL
|
|||||||
func validateKubeFinalizerName(stringValue string, fldPath *field.Path) field.ErrorList {
|
func validateKubeFinalizerName(stringValue string, fldPath *field.Path) field.ErrorList {
|
||||||
allErrs := field.ErrorList{}
|
allErrs := field.ErrorList{}
|
||||||
if len(strings.Split(stringValue, "/")) == 1 {
|
if len(strings.Split(stringValue, "/")) == 1 {
|
||||||
if !api.IsStandardFinalizerName(stringValue) {
|
if !helper.IsStandardFinalizerName(stringValue) {
|
||||||
return append(allErrs, field.Invalid(fldPath, stringValue, "name is neither a standard finalizer name nor is it fully qualified"))
|
return append(allErrs, field.Invalid(fldPath, stringValue, "name is neither a standard finalizer name nor is it fully qualified"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,6 +27,7 @@ import (
|
|||||||
"k8s.io/apimachinery/pkg/util/sets"
|
"k8s.io/apimachinery/pkg/util/sets"
|
||||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
|
"k8s.io/kubernetes/pkg/api/helper"
|
||||||
"k8s.io/kubernetes/pkg/api/service"
|
"k8s.io/kubernetes/pkg/api/service"
|
||||||
"k8s.io/kubernetes/pkg/api/v1"
|
"k8s.io/kubernetes/pkg/api/v1"
|
||||||
"k8s.io/kubernetes/pkg/capabilities"
|
"k8s.io/kubernetes/pkg/capabilities"
|
||||||
@ -3712,10 +3713,10 @@ func TestValidatePod(t *testing.T) {
|
|||||||
ImagePullPolicy: "IfNotPresent",
|
ImagePullPolicy: "IfNotPresent",
|
||||||
Resources: api.ResourceRequirements{
|
Resources: api.ResourceRequirements{
|
||||||
Requests: api.ResourceList{
|
Requests: api.ResourceList{
|
||||||
api.OpaqueIntResourceName("A"): resource.MustParse("10"),
|
helper.OpaqueIntResourceName("A"): resource.MustParse("10"),
|
||||||
},
|
},
|
||||||
Limits: api.ResourceList{
|
Limits: api.ResourceList{
|
||||||
api.OpaqueIntResourceName("A"): resource.MustParse("20"),
|
helper.OpaqueIntResourceName("A"): resource.MustParse("20"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
TerminationMessagePolicy: "File",
|
TerminationMessagePolicy: "File",
|
||||||
@ -3737,10 +3738,10 @@ func TestValidatePod(t *testing.T) {
|
|||||||
ImagePullPolicy: "IfNotPresent",
|
ImagePullPolicy: "IfNotPresent",
|
||||||
Resources: api.ResourceRequirements{
|
Resources: api.ResourceRequirements{
|
||||||
Requests: api.ResourceList{
|
Requests: api.ResourceList{
|
||||||
api.OpaqueIntResourceName("A"): resource.MustParse("10"),
|
helper.OpaqueIntResourceName("A"): resource.MustParse("10"),
|
||||||
},
|
},
|
||||||
Limits: api.ResourceList{
|
Limits: api.ResourceList{
|
||||||
api.OpaqueIntResourceName("A"): resource.MustParse("20"),
|
helper.OpaqueIntResourceName("A"): resource.MustParse("20"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
TerminationMessagePolicy: "File",
|
TerminationMessagePolicy: "File",
|
||||||
@ -4211,10 +4212,10 @@ func TestValidatePod(t *testing.T) {
|
|||||||
ImagePullPolicy: "IfNotPresent",
|
ImagePullPolicy: "IfNotPresent",
|
||||||
Resources: api.ResourceRequirements{
|
Resources: api.ResourceRequirements{
|
||||||
Requests: api.ResourceList{
|
Requests: api.ResourceList{
|
||||||
api.OpaqueIntResourceName("A"): resource.MustParse("2"),
|
helper.OpaqueIntResourceName("A"): resource.MustParse("2"),
|
||||||
},
|
},
|
||||||
Limits: api.ResourceList{
|
Limits: api.ResourceList{
|
||||||
api.OpaqueIntResourceName("A"): resource.MustParse("1"),
|
helper.OpaqueIntResourceName("A"): resource.MustParse("1"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -4233,7 +4234,7 @@ func TestValidatePod(t *testing.T) {
|
|||||||
ImagePullPolicy: "IfNotPresent",
|
ImagePullPolicy: "IfNotPresent",
|
||||||
Resources: api.ResourceRequirements{
|
Resources: api.ResourceRequirements{
|
||||||
Requests: api.ResourceList{
|
Requests: api.ResourceList{
|
||||||
api.OpaqueIntResourceName("A"): resource.MustParse("500m"),
|
helper.OpaqueIntResourceName("A"): resource.MustParse("500m"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -4252,7 +4253,7 @@ func TestValidatePod(t *testing.T) {
|
|||||||
ImagePullPolicy: "IfNotPresent",
|
ImagePullPolicy: "IfNotPresent",
|
||||||
Resources: api.ResourceRequirements{
|
Resources: api.ResourceRequirements{
|
||||||
Requests: api.ResourceList{
|
Requests: api.ResourceList{
|
||||||
api.OpaqueIntResourceName("A"): resource.MustParse("500m"),
|
helper.OpaqueIntResourceName("A"): resource.MustParse("500m"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -4272,10 +4273,10 @@ func TestValidatePod(t *testing.T) {
|
|||||||
ImagePullPolicy: "IfNotPresent",
|
ImagePullPolicy: "IfNotPresent",
|
||||||
Resources: api.ResourceRequirements{
|
Resources: api.ResourceRequirements{
|
||||||
Requests: api.ResourceList{
|
Requests: api.ResourceList{
|
||||||
api.OpaqueIntResourceName("A"): resource.MustParse("5"),
|
helper.OpaqueIntResourceName("A"): resource.MustParse("5"),
|
||||||
},
|
},
|
||||||
Limits: api.ResourceList{
|
Limits: api.ResourceList{
|
||||||
api.OpaqueIntResourceName("A"): resource.MustParse("2.5"),
|
helper.OpaqueIntResourceName("A"): resource.MustParse("2.5"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -4294,10 +4295,10 @@ func TestValidatePod(t *testing.T) {
|
|||||||
ImagePullPolicy: "IfNotPresent",
|
ImagePullPolicy: "IfNotPresent",
|
||||||
Resources: api.ResourceRequirements{
|
Resources: api.ResourceRequirements{
|
||||||
Requests: api.ResourceList{
|
Requests: api.ResourceList{
|
||||||
api.OpaqueIntResourceName("A"): resource.MustParse("5"),
|
helper.OpaqueIntResourceName("A"): resource.MustParse("5"),
|
||||||
},
|
},
|
||||||
Limits: api.ResourceList{
|
Limits: api.ResourceList{
|
||||||
api.OpaqueIntResourceName("A"): resource.MustParse("2.5"),
|
helper.OpaqueIntResourceName("A"): resource.MustParse("2.5"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -6739,8 +6740,8 @@ func TestValidateNodeUpdate(t *testing.T) {
|
|||||||
Capacity: api.ResourceList{
|
Capacity: api.ResourceList{
|
||||||
api.ResourceName(api.ResourceCPU): resource.MustParse("10"),
|
api.ResourceName(api.ResourceCPU): resource.MustParse("10"),
|
||||||
api.ResourceName(api.ResourceMemory): resource.MustParse("10G"),
|
api.ResourceName(api.ResourceMemory): resource.MustParse("10G"),
|
||||||
api.OpaqueIntResourceName("A"): resource.MustParse("5"),
|
helper.OpaqueIntResourceName("A"): resource.MustParse("5"),
|
||||||
api.OpaqueIntResourceName("B"): resource.MustParse("10"),
|
helper.OpaqueIntResourceName("B"): resource.MustParse("10"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}, true},
|
}, true},
|
||||||
@ -6756,7 +6757,7 @@ func TestValidateNodeUpdate(t *testing.T) {
|
|||||||
Capacity: api.ResourceList{
|
Capacity: api.ResourceList{
|
||||||
api.ResourceName(api.ResourceCPU): resource.MustParse("10"),
|
api.ResourceName(api.ResourceCPU): resource.MustParse("10"),
|
||||||
api.ResourceName(api.ResourceMemory): resource.MustParse("10G"),
|
api.ResourceName(api.ResourceMemory): resource.MustParse("10G"),
|
||||||
api.OpaqueIntResourceName("A"): resource.MustParse("500m"),
|
helper.OpaqueIntResourceName("A"): resource.MustParse("500m"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}, false},
|
}, false},
|
||||||
@ -6772,12 +6773,12 @@ func TestValidateNodeUpdate(t *testing.T) {
|
|||||||
Capacity: api.ResourceList{
|
Capacity: api.ResourceList{
|
||||||
api.ResourceName(api.ResourceCPU): resource.MustParse("10"),
|
api.ResourceName(api.ResourceCPU): resource.MustParse("10"),
|
||||||
api.ResourceName(api.ResourceMemory): resource.MustParse("10G"),
|
api.ResourceName(api.ResourceMemory): resource.MustParse("10G"),
|
||||||
api.OpaqueIntResourceName("A"): resource.MustParse("5"),
|
helper.OpaqueIntResourceName("A"): resource.MustParse("5"),
|
||||||
},
|
},
|
||||||
Allocatable: api.ResourceList{
|
Allocatable: api.ResourceList{
|
||||||
api.ResourceName(api.ResourceCPU): resource.MustParse("10"),
|
api.ResourceName(api.ResourceCPU): resource.MustParse("10"),
|
||||||
api.ResourceName(api.ResourceMemory): resource.MustParse("10G"),
|
api.ResourceName(api.ResourceMemory): resource.MustParse("10G"),
|
||||||
api.OpaqueIntResourceName("A"): resource.MustParse("4.5"),
|
helper.OpaqueIntResourceName("A"): resource.MustParse("4.5"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}, false},
|
}, false},
|
||||||
|
@ -65,7 +65,6 @@ func RegisterDeepCopies(scheme *runtime.Scheme) error {
|
|||||||
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_api_ContainerStateTerminated, InType: reflect.TypeOf(&ContainerStateTerminated{})},
|
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_api_ContainerStateTerminated, InType: reflect.TypeOf(&ContainerStateTerminated{})},
|
||||||
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_api_ContainerStateWaiting, InType: reflect.TypeOf(&ContainerStateWaiting{})},
|
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_api_ContainerStateWaiting, InType: reflect.TypeOf(&ContainerStateWaiting{})},
|
||||||
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_api_ContainerStatus, InType: reflect.TypeOf(&ContainerStatus{})},
|
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_api_ContainerStatus, InType: reflect.TypeOf(&ContainerStatus{})},
|
||||||
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_api_ConversionError, InType: reflect.TypeOf(&ConversionError{})},
|
|
||||||
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_api_DaemonEndpoint, InType: reflect.TypeOf(&DaemonEndpoint{})},
|
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_api_DaemonEndpoint, InType: reflect.TypeOf(&DaemonEndpoint{})},
|
||||||
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_api_DeleteOptions, InType: reflect.TypeOf(&DeleteOptions{})},
|
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_api_DeleteOptions, InType: reflect.TypeOf(&DeleteOptions{})},
|
||||||
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_api_DownwardAPIProjection, InType: reflect.TypeOf(&DownwardAPIProjection{})},
|
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_api_DownwardAPIProjection, InType: reflect.TypeOf(&DownwardAPIProjection{})},
|
||||||
@ -707,31 +706,6 @@ func DeepCopy_api_ContainerStatus(in interface{}, out interface{}, c *conversion
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func DeepCopy_api_ConversionError(in interface{}, out interface{}, c *conversion.Cloner) error {
|
|
||||||
{
|
|
||||||
in := in.(*ConversionError)
|
|
||||||
out := out.(*ConversionError)
|
|
||||||
*out = *in
|
|
||||||
// in.In is kind 'Interface'
|
|
||||||
if in.In != nil {
|
|
||||||
if newVal, err := c.DeepCopy(&in.In); err != nil {
|
|
||||||
return err
|
|
||||||
} else {
|
|
||||||
out.In = *newVal.(*interface{})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// in.Out is kind 'Interface'
|
|
||||||
if in.Out != nil {
|
|
||||||
if newVal, err := c.DeepCopy(&in.Out); err != nil {
|
|
||||||
return err
|
|
||||||
} else {
|
|
||||||
out.Out = *newVal.(*interface{})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func DeepCopy_api_DaemonEndpoint(in interface{}, out interface{}, c *conversion.Cloner) error {
|
func DeepCopy_api_DaemonEndpoint(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||||
{
|
{
|
||||||
in := in.(*DaemonEndpoint)
|
in := in.(*DaemonEndpoint)
|
||||||
|
@ -27,6 +27,7 @@ go_test(
|
|||||||
"//vendor:k8s.io/apimachinery/pkg/runtime/schema",
|
"//vendor:k8s.io/apimachinery/pkg/runtime/schema",
|
||||||
"//vendor:k8s.io/client-go/kubernetes/fake",
|
"//vendor:k8s.io/client-go/kubernetes/fake",
|
||||||
"//vendor:k8s.io/client-go/pkg/api",
|
"//vendor:k8s.io/client-go/pkg/api",
|
||||||
|
"//vendor:k8s.io/client-go/pkg/api/helper",
|
||||||
"//vendor:k8s.io/client-go/pkg/api/v1",
|
"//vendor:k8s.io/client-go/pkg/api/v1",
|
||||||
"//vendor:k8s.io/client-go/testing",
|
"//vendor:k8s.io/client-go/testing",
|
||||||
],
|
],
|
||||||
|
@ -22,7 +22,7 @@ import (
|
|||||||
"github.com/davecgh/go-spew/spew"
|
"github.com/davecgh/go-spew/spew"
|
||||||
|
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/client-go/pkg/api"
|
"k8s.io/client-go/pkg/api/helper"
|
||||||
"k8s.io/client-go/pkg/api/v1"
|
"k8s.io/client-go/pkg/api/v1"
|
||||||
core "k8s.io/client-go/testing"
|
core "k8s.io/client-go/testing"
|
||||||
bootstrapapi "k8s.io/kubernetes/pkg/bootstrap/api"
|
bootstrapapi "k8s.io/kubernetes/pkg/bootstrap/api"
|
||||||
@ -59,7 +59,7 @@ func verifyActions(t *testing.T, expected, actual []core.Action) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
e := expected[i]
|
e := expected[i]
|
||||||
if !api.Semantic.DeepEqual(e, a) {
|
if !helper.Semantic.DeepEqual(e, a) {
|
||||||
t.Errorf("Expected\n\t%s\ngot\n\t%s", spew.Sdump(e), spew.Sdump(a))
|
t.Errorf("Expected\n\t%s\ngot\n\t%s", spew.Sdump(e), spew.Sdump(a))
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -64,6 +64,7 @@ go_library(
|
|||||||
tags = ["automanaged"],
|
tags = ["automanaged"],
|
||||||
deps = [
|
deps = [
|
||||||
"//pkg/api:go_default_library",
|
"//pkg/api:go_default_library",
|
||||||
|
"//pkg/api/helper:go_default_library",
|
||||||
"//pkg/api/v1:go_default_library",
|
"//pkg/api/v1:go_default_library",
|
||||||
"//pkg/client/clientset_generated/clientset:go_default_library",
|
"//pkg/client/clientset_generated/clientset:go_default_library",
|
||||||
"//pkg/client/informers/informers_generated/externalversions/core/v1:go_default_library",
|
"//pkg/client/informers/informers_generated/externalversions/core/v1:go_default_library",
|
||||||
|
@ -22,6 +22,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
|
"k8s.io/kubernetes/pkg/api/helper"
|
||||||
"k8s.io/kubernetes/pkg/api/v1"
|
"k8s.io/kubernetes/pkg/api/v1"
|
||||||
"k8s.io/kubernetes/pkg/client/clientset_generated/clientset"
|
"k8s.io/kubernetes/pkg/client/clientset_generated/clientset"
|
||||||
|
|
||||||
@ -248,7 +249,7 @@ func (tc *NoExecuteTaintManager) PodUpdated(oldPod *v1.Pod, newPod *v1.Pod) {
|
|||||||
newTolerations = newPod.Spec.Tolerations
|
newTolerations = newPod.Spec.Tolerations
|
||||||
}
|
}
|
||||||
|
|
||||||
if oldPod != nil && newPod != nil && api.Semantic.DeepEqual(oldTolerations, newTolerations) && oldPod.Spec.NodeName == newPod.Spec.NodeName {
|
if oldPod != nil && newPod != nil && helper.Semantic.DeepEqual(oldTolerations, newTolerations) && oldPod.Spec.NodeName == newPod.Spec.NodeName {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
updateItem := &podUpdateItem{
|
updateItem := &podUpdateItem{
|
||||||
@ -274,7 +275,7 @@ func (tc *NoExecuteTaintManager) NodeUpdated(oldNode *v1.Node, newNode *v1.Node)
|
|||||||
}
|
}
|
||||||
newTaints = getNoExecuteTaints(newTaints)
|
newTaints = getNoExecuteTaints(newTaints)
|
||||||
|
|
||||||
if oldNode != nil && newNode != nil && api.Semantic.DeepEqual(oldTaints, newTaints) {
|
if oldNode != nil && newNode != nil && helper.Semantic.DeepEqual(oldTaints, newTaints) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
updateItem := &nodeUpdateItem{
|
updateItem := &nodeUpdateItem{
|
||||||
|
@ -51,6 +51,7 @@ go_library(
|
|||||||
"//federation/apis/federation/v1beta1:go_default_library",
|
"//federation/apis/federation/v1beta1:go_default_library",
|
||||||
"//pkg/api:go_default_library",
|
"//pkg/api:go_default_library",
|
||||||
"//pkg/api/annotations:go_default_library",
|
"//pkg/api/annotations:go_default_library",
|
||||||
|
"//pkg/api/helper:go_default_library",
|
||||||
"//pkg/api/util:go_default_library",
|
"//pkg/api/util:go_default_library",
|
||||||
"//pkg/api/v1:go_default_library",
|
"//pkg/api/v1:go_default_library",
|
||||||
"//pkg/apis/apps:go_default_library",
|
"//pkg/apis/apps:go_default_library",
|
||||||
@ -139,6 +140,7 @@ go_test(
|
|||||||
deps = [
|
deps = [
|
||||||
"//federation/apis/federation/v1beta1:go_default_library",
|
"//federation/apis/federation/v1beta1:go_default_library",
|
||||||
"//pkg/api:go_default_library",
|
"//pkg/api:go_default_library",
|
||||||
|
"//pkg/api/helper:go_default_library",
|
||||||
"//pkg/api/testapi:go_default_library",
|
"//pkg/api/testapi:go_default_library",
|
||||||
"//pkg/api/testing:go_default_library",
|
"//pkg/api/testing:go_default_library",
|
||||||
"//pkg/api/v1:go_default_library",
|
"//pkg/api/v1:go_default_library",
|
||||||
|
@ -68,6 +68,7 @@ go_library(
|
|||||||
deps = [
|
deps = [
|
||||||
"//pkg/api:go_default_library",
|
"//pkg/api:go_default_library",
|
||||||
"//pkg/api/annotations:go_default_library",
|
"//pkg/api/annotations:go_default_library",
|
||||||
|
"//pkg/api/helper:go_default_library",
|
||||||
"//pkg/api/v1:go_default_library",
|
"//pkg/api/v1:go_default_library",
|
||||||
"//pkg/api/validation:go_default_library",
|
"//pkg/api/validation:go_default_library",
|
||||||
"//pkg/apis/apps/v1beta1:go_default_library",
|
"//pkg/apis/apps/v1beta1:go_default_library",
|
||||||
|
@ -29,6 +29,7 @@ import (
|
|||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
restclient "k8s.io/client-go/rest"
|
restclient "k8s.io/client-go/rest"
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
|
"k8s.io/kubernetes/pkg/api/helper"
|
||||||
"k8s.io/kubernetes/pkg/api/validation"
|
"k8s.io/kubernetes/pkg/api/validation"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
@ -157,7 +158,7 @@ func (o *LogsOptions) Complete(f cmdutil.Factory, out io.Writer, cmd *cobra.Comm
|
|||||||
Timestamps: cmdutil.GetFlagBool(cmd, "timestamps"),
|
Timestamps: cmdutil.GetFlagBool(cmd, "timestamps"),
|
||||||
}
|
}
|
||||||
if sinceTime := cmdutil.GetFlagString(cmd, "since-time"); len(sinceTime) > 0 {
|
if sinceTime := cmdutil.GetFlagString(cmd, "since-time"); len(sinceTime) > 0 {
|
||||||
t, err := api.ParseRFC3339(sinceTime, metav1.Now)
|
t, err := helper.ParseRFC3339(sinceTime, metav1.Now)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -33,6 +33,7 @@ import (
|
|||||||
utilerrors "k8s.io/apimachinery/pkg/util/errors"
|
utilerrors "k8s.io/apimachinery/pkg/util/errors"
|
||||||
"k8s.io/apimachinery/pkg/util/intstr"
|
"k8s.io/apimachinery/pkg/util/intstr"
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
|
"k8s.io/kubernetes/pkg/api/helper"
|
||||||
"k8s.io/kubernetes/pkg/api/v1"
|
"k8s.io/kubernetes/pkg/api/v1"
|
||||||
"k8s.io/kubernetes/pkg/kubectl"
|
"k8s.io/kubernetes/pkg/kubectl"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||||
@ -278,7 +279,7 @@ func RunRollingUpdate(f cmdutil.Factory, out io.Writer, cmd *cobra.Command, args
|
|||||||
}
|
}
|
||||||
// Update the existing replication controller with pointers to the 'next' controller
|
// Update the existing replication controller with pointers to the 'next' controller
|
||||||
// and adding the <deploymentKey> label if necessary to distinguish it from the 'next' controller.
|
// and adding the <deploymentKey> label if necessary to distinguish it from the 'next' controller.
|
||||||
oldHash, err := api.HashObject(oldRc, codec)
|
oldHash, err := helper.HashObject(oldRc, codec)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -32,6 +32,7 @@ import (
|
|||||||
"k8s.io/apimachinery/pkg/util/wait"
|
"k8s.io/apimachinery/pkg/util/wait"
|
||||||
"k8s.io/client-go/util/integer"
|
"k8s.io/client-go/util/integer"
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
|
"k8s.io/kubernetes/pkg/api/helper"
|
||||||
"k8s.io/kubernetes/pkg/api/v1"
|
"k8s.io/kubernetes/pkg/api/v1"
|
||||||
coreclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/internalversion"
|
coreclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/internalversion"
|
||||||
"k8s.io/kubernetes/pkg/client/retry"
|
"k8s.io/kubernetes/pkg/client/retry"
|
||||||
@ -625,7 +626,7 @@ func CreateNewControllerFromCurrentController(rcClient coreclient.ReplicationCon
|
|||||||
newRc.Spec.Template.Spec.Containers[containerIndex].ImagePullPolicy = cfg.PullPolicy
|
newRc.Spec.Template.Spec.Containers[containerIndex].ImagePullPolicy = cfg.PullPolicy
|
||||||
}
|
}
|
||||||
|
|
||||||
newHash, err := api.HashObject(newRc, codec)
|
newHash, err := helper.HashObject(newRc, codec)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -37,6 +37,7 @@ import (
|
|||||||
manualfake "k8s.io/client-go/rest/fake"
|
manualfake "k8s.io/client-go/rest/fake"
|
||||||
testcore "k8s.io/client-go/testing"
|
testcore "k8s.io/client-go/testing"
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
|
"k8s.io/kubernetes/pkg/api/helper"
|
||||||
"k8s.io/kubernetes/pkg/api/testapi"
|
"k8s.io/kubernetes/pkg/api/testapi"
|
||||||
apitesting "k8s.io/kubernetes/pkg/api/testing"
|
apitesting "k8s.io/kubernetes/pkg/api/testing"
|
||||||
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
|
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
|
||||||
@ -1076,7 +1077,7 @@ func TestRollingUpdater_multipleContainersInPod(t *testing.T) {
|
|||||||
|
|
||||||
codec := testapi.Default.Codec()
|
codec := testapi.Default.Codec()
|
||||||
|
|
||||||
deploymentHash, err := api.HashObject(test.newRc, codec)
|
deploymentHash, err := helper.HashObject(test.newRc, codec)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("unexpected error: %v", err)
|
t.Errorf("unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,7 @@ go_library(
|
|||||||
tags = ["automanaged"],
|
tags = ["automanaged"],
|
||||||
deps = [
|
deps = [
|
||||||
"//pkg/api:go_default_library",
|
"//pkg/api:go_default_library",
|
||||||
|
"//pkg/api/helper:go_default_library",
|
||||||
"//pkg/api/v1:go_default_library",
|
"//pkg/api/v1:go_default_library",
|
||||||
"//pkg/api/v1/pod:go_default_library",
|
"//pkg/api/v1/pod:go_default_library",
|
||||||
"//pkg/api/validation:go_default_library",
|
"//pkg/api/validation:go_default_library",
|
||||||
|
@ -27,6 +27,7 @@ import (
|
|||||||
"k8s.io/apimachinery/pkg/types"
|
"k8s.io/apimachinery/pkg/types"
|
||||||
utilyaml "k8s.io/apimachinery/pkg/util/yaml"
|
utilyaml "k8s.io/apimachinery/pkg/util/yaml"
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
|
"k8s.io/kubernetes/pkg/api/helper"
|
||||||
"k8s.io/kubernetes/pkg/api/v1"
|
"k8s.io/kubernetes/pkg/api/v1"
|
||||||
"k8s.io/kubernetes/pkg/api/validation"
|
"k8s.io/kubernetes/pkg/api/validation"
|
||||||
kubetypes "k8s.io/kubernetes/pkg/kubelet/types"
|
kubetypes "k8s.io/kubernetes/pkg/kubelet/types"
|
||||||
@ -76,7 +77,7 @@ func applyDefaults(pod *api.Pod, source string, isFile bool, nodeName types.Node
|
|||||||
if isFile {
|
if isFile {
|
||||||
// Applying the default Taint tolerations to static pods,
|
// Applying the default Taint tolerations to static pods,
|
||||||
// so they are not evicted when there are node problems.
|
// so they are not evicted when there are node problems.
|
||||||
api.AddOrUpdateTolerationInPod(pod, &api.Toleration{
|
helper.AddOrUpdateTolerationInPod(pod, &api.Toleration{
|
||||||
Operator: "Exists",
|
Operator: "Exists",
|
||||||
Effect: api.TaintEffectNoExecute,
|
Effect: api.TaintEffectNoExecute,
|
||||||
})
|
})
|
||||||
|
@ -62,6 +62,7 @@ go_library(
|
|||||||
"//pkg/api:go_default_library",
|
"//pkg/api:go_default_library",
|
||||||
"//pkg/api/annotations:go_default_library",
|
"//pkg/api/annotations:go_default_library",
|
||||||
"//pkg/api/events:go_default_library",
|
"//pkg/api/events:go_default_library",
|
||||||
|
"//pkg/api/helper:go_default_library",
|
||||||
"//pkg/apis/apps:go_default_library",
|
"//pkg/apis/apps:go_default_library",
|
||||||
"//pkg/apis/autoscaling:go_default_library",
|
"//pkg/apis/autoscaling:go_default_library",
|
||||||
"//pkg/apis/batch:go_default_library",
|
"//pkg/apis/batch:go_default_library",
|
||||||
|
@ -47,6 +47,7 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
"k8s.io/kubernetes/pkg/api/annotations"
|
"k8s.io/kubernetes/pkg/api/annotations"
|
||||||
"k8s.io/kubernetes/pkg/api/events"
|
"k8s.io/kubernetes/pkg/api/events"
|
||||||
|
"k8s.io/kubernetes/pkg/api/helper"
|
||||||
"k8s.io/kubernetes/pkg/apis/apps"
|
"k8s.io/kubernetes/pkg/apis/apps"
|
||||||
"k8s.io/kubernetes/pkg/apis/autoscaling"
|
"k8s.io/kubernetes/pkg/apis/autoscaling"
|
||||||
"k8s.io/kubernetes/pkg/apis/batch"
|
"k8s.io/kubernetes/pkg/apis/batch"
|
||||||
@ -847,7 +848,7 @@ func (d *PersistentVolumeDescriber) Describe(namespace, name string, describerSe
|
|||||||
w.Write(LEVEL_0, "Name:\t%s\n", pv.Name)
|
w.Write(LEVEL_0, "Name:\t%s\n", pv.Name)
|
||||||
printLabelsMultiline(w, "Labels", pv.Labels)
|
printLabelsMultiline(w, "Labels", pv.Labels)
|
||||||
printAnnotationsMultiline(w, "Annotations", pv.Annotations)
|
printAnnotationsMultiline(w, "Annotations", pv.Annotations)
|
||||||
w.Write(LEVEL_0, "StorageClass:\t%s\n", api.GetPersistentVolumeClass(pv))
|
w.Write(LEVEL_0, "StorageClass:\t%s\n", helper.GetPersistentVolumeClass(pv))
|
||||||
w.Write(LEVEL_0, "Status:\t%s\n", pv.Status.Phase)
|
w.Write(LEVEL_0, "Status:\t%s\n", pv.Status.Phase)
|
||||||
if pv.Spec.ClaimRef != nil {
|
if pv.Spec.ClaimRef != nil {
|
||||||
w.Write(LEVEL_0, "Claim:\t%s\n", pv.Spec.ClaimRef.Namespace+"/"+pv.Spec.ClaimRef.Name)
|
w.Write(LEVEL_0, "Claim:\t%s\n", pv.Spec.ClaimRef.Namespace+"/"+pv.Spec.ClaimRef.Name)
|
||||||
@ -855,7 +856,7 @@ func (d *PersistentVolumeDescriber) Describe(namespace, name string, describerSe
|
|||||||
w.Write(LEVEL_0, "Claim:\t%s\n", "")
|
w.Write(LEVEL_0, "Claim:\t%s\n", "")
|
||||||
}
|
}
|
||||||
w.Write(LEVEL_0, "Reclaim Policy:\t%v\n", pv.Spec.PersistentVolumeReclaimPolicy)
|
w.Write(LEVEL_0, "Reclaim Policy:\t%v\n", pv.Spec.PersistentVolumeReclaimPolicy)
|
||||||
w.Write(LEVEL_0, "Access Modes:\t%s\n", api.GetAccessModesAsString(pv.Spec.AccessModes))
|
w.Write(LEVEL_0, "Access Modes:\t%s\n", helper.GetAccessModesAsString(pv.Spec.AccessModes))
|
||||||
w.Write(LEVEL_0, "Capacity:\t%s\n", storage.String())
|
w.Write(LEVEL_0, "Capacity:\t%s\n", storage.String())
|
||||||
w.Write(LEVEL_0, "Message:\t%s\n", pv.Status.Message)
|
w.Write(LEVEL_0, "Message:\t%s\n", pv.Status.Message)
|
||||||
w.Write(LEVEL_0, "Source:\n")
|
w.Write(LEVEL_0, "Source:\n")
|
||||||
@ -915,7 +916,7 @@ func (d *PersistentVolumeClaimDescriber) Describe(namespace, name string, descri
|
|||||||
capacity := ""
|
capacity := ""
|
||||||
accessModes := ""
|
accessModes := ""
|
||||||
if pvc.Spec.VolumeName != "" {
|
if pvc.Spec.VolumeName != "" {
|
||||||
accessModes = api.GetAccessModesAsString(pvc.Status.AccessModes)
|
accessModes = helper.GetAccessModesAsString(pvc.Status.AccessModes)
|
||||||
storage = pvc.Status.Capacity[api.ResourceStorage]
|
storage = pvc.Status.Capacity[api.ResourceStorage]
|
||||||
capacity = storage.String()
|
capacity = storage.String()
|
||||||
}
|
}
|
||||||
@ -926,7 +927,7 @@ func (d *PersistentVolumeClaimDescriber) Describe(namespace, name string, descri
|
|||||||
w := NewPrefixWriter(out)
|
w := NewPrefixWriter(out)
|
||||||
w.Write(LEVEL_0, "Name:\t%s\n", pvc.Name)
|
w.Write(LEVEL_0, "Name:\t%s\n", pvc.Name)
|
||||||
w.Write(LEVEL_0, "Namespace:\t%s\n", pvc.Namespace)
|
w.Write(LEVEL_0, "Namespace:\t%s\n", pvc.Namespace)
|
||||||
w.Write(LEVEL_0, "StorageClass:\t%s\n", api.GetPersistentVolumeClaimClass(pvc))
|
w.Write(LEVEL_0, "StorageClass:\t%s\n", helper.GetPersistentVolumeClaimClass(pvc))
|
||||||
w.Write(LEVEL_0, "Status:\t%v\n", pvc.Status.Phase)
|
w.Write(LEVEL_0, "Status:\t%v\n", pvc.Status.Phase)
|
||||||
w.Write(LEVEL_0, "Volume:\t%s\n", pvc.Spec.VolumeName)
|
w.Write(LEVEL_0, "Volume:\t%s\n", pvc.Spec.VolumeName)
|
||||||
printLabelsMultiline(w, "Labels", pvc.Labels)
|
printLabelsMultiline(w, "Labels", pvc.Labels)
|
||||||
@ -1225,7 +1226,7 @@ func describeVolumeClaimTemplates(templates []api.PersistentVolumeClaim, w Prefi
|
|||||||
w.Write(LEVEL_0, "Volume Claims:\n")
|
w.Write(LEVEL_0, "Volume Claims:\n")
|
||||||
for _, pvc := range templates {
|
for _, pvc := range templates {
|
||||||
w.Write(LEVEL_1, "Name:\t%s\n", pvc.Name)
|
w.Write(LEVEL_1, "Name:\t%s\n", pvc.Name)
|
||||||
w.Write(LEVEL_1, "StorageClass:\t%s\n", api.GetPersistentVolumeClaimClass(&pvc))
|
w.Write(LEVEL_1, "StorageClass:\t%s\n", helper.GetPersistentVolumeClaimClass(&pvc))
|
||||||
printLabelsMultilineWithIndent(w, " ", "Labels", "\t", pvc.Labels, sets.NewString())
|
printLabelsMultilineWithIndent(w, " ", "Labels", "\t", pvc.Labels, sets.NewString())
|
||||||
printLabelsMultilineWithIndent(w, " ", "Annotations", "\t", pvc.Annotations, sets.NewString())
|
printLabelsMultilineWithIndent(w, " ", "Annotations", "\t", pvc.Annotations, sets.NewString())
|
||||||
if capacity, ok := pvc.Spec.Resources.Requests[api.ResourceStorage]; ok {
|
if capacity, ok := pvc.Spec.Resources.Requests[api.ResourceStorage]; ok {
|
||||||
|
@ -32,6 +32,7 @@ import (
|
|||||||
"k8s.io/kubernetes/federation/apis/federation"
|
"k8s.io/kubernetes/federation/apis/federation"
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
"k8s.io/kubernetes/pkg/api/events"
|
"k8s.io/kubernetes/pkg/api/events"
|
||||||
|
"k8s.io/kubernetes/pkg/api/helper"
|
||||||
"k8s.io/kubernetes/pkg/apis/apps"
|
"k8s.io/kubernetes/pkg/apis/apps"
|
||||||
"k8s.io/kubernetes/pkg/apis/autoscaling"
|
"k8s.io/kubernetes/pkg/apis/autoscaling"
|
||||||
"k8s.io/kubernetes/pkg/apis/batch"
|
"k8s.io/kubernetes/pkg/apis/batch"
|
||||||
@ -1175,7 +1176,7 @@ func printPersistentVolume(pv *api.PersistentVolume, w io.Writer, options printe
|
|||||||
claimRefUID += pv.Spec.ClaimRef.Name
|
claimRefUID += pv.Spec.ClaimRef.Name
|
||||||
}
|
}
|
||||||
|
|
||||||
modesStr := api.GetAccessModesAsString(pv.Spec.AccessModes)
|
modesStr := helper.GetAccessModesAsString(pv.Spec.AccessModes)
|
||||||
reclaimPolicyStr := string(pv.Spec.PersistentVolumeReclaimPolicy)
|
reclaimPolicyStr := string(pv.Spec.PersistentVolumeReclaimPolicy)
|
||||||
|
|
||||||
aQty := pv.Spec.Capacity[api.ResourceStorage]
|
aQty := pv.Spec.Capacity[api.ResourceStorage]
|
||||||
@ -1186,7 +1187,7 @@ func printPersistentVolume(pv *api.PersistentVolume, w io.Writer, options printe
|
|||||||
aSize, modesStr, reclaimPolicyStr,
|
aSize, modesStr, reclaimPolicyStr,
|
||||||
pv.Status.Phase,
|
pv.Status.Phase,
|
||||||
claimRefUID,
|
claimRefUID,
|
||||||
api.GetPersistentVolumeClass(pv),
|
helper.GetPersistentVolumeClass(pv),
|
||||||
pv.Status.Reason,
|
pv.Status.Reason,
|
||||||
translateTimestamp(pv.CreationTimestamp),
|
translateTimestamp(pv.CreationTimestamp),
|
||||||
); err != nil {
|
); err != nil {
|
||||||
@ -1224,12 +1225,12 @@ func printPersistentVolumeClaim(pvc *api.PersistentVolumeClaim, w io.Writer, opt
|
|||||||
capacity := ""
|
capacity := ""
|
||||||
accessModes := ""
|
accessModes := ""
|
||||||
if pvc.Spec.VolumeName != "" {
|
if pvc.Spec.VolumeName != "" {
|
||||||
accessModes = api.GetAccessModesAsString(pvc.Status.AccessModes)
|
accessModes = helper.GetAccessModesAsString(pvc.Status.AccessModes)
|
||||||
storage = pvc.Status.Capacity[api.ResourceStorage]
|
storage = pvc.Status.Capacity[api.ResourceStorage]
|
||||||
capacity = storage.String()
|
capacity = storage.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s\t%s\t%s", name, phase, pvc.Spec.VolumeName, capacity, accessModes, api.GetPersistentVolumeClaimClass(pvc), translateTimestamp(pvc.CreationTimestamp)); err != nil {
|
if _, err := fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s\t%s\t%s", name, phase, pvc.Spec.VolumeName, capacity, accessModes, helper.GetPersistentVolumeClaimClass(pvc), translateTimestamp(pvc.CreationTimestamp)); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if _, err := fmt.Fprint(w, AppendLabels(pvc.Labels, options.ColumnLabels)); err != nil {
|
if _, err := fmt.Fprint(w, AppendLabels(pvc.Labels, options.ColumnLabels)); err != nil {
|
||||||
|
@ -14,6 +14,7 @@ go_library(
|
|||||||
tags = ["automanaged"],
|
tags = ["automanaged"],
|
||||||
deps = [
|
deps = [
|
||||||
"//pkg/api:go_default_library",
|
"//pkg/api:go_default_library",
|
||||||
|
"//pkg/api/helper:go_default_library",
|
||||||
"//pkg/api/service:go_default_library",
|
"//pkg/api/service:go_default_library",
|
||||||
"//pkg/features:go_default_library",
|
"//pkg/features:go_default_library",
|
||||||
"//pkg/proxy:go_default_library",
|
"//pkg/proxy:go_default_library",
|
||||||
|
@ -42,6 +42,7 @@ import (
|
|||||||
"k8s.io/client-go/tools/record"
|
"k8s.io/client-go/tools/record"
|
||||||
"k8s.io/client-go/util/flowcontrol"
|
"k8s.io/client-go/util/flowcontrol"
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
|
"k8s.io/kubernetes/pkg/api/helper"
|
||||||
apiservice "k8s.io/kubernetes/pkg/api/service"
|
apiservice "k8s.io/kubernetes/pkg/api/service"
|
||||||
"k8s.io/kubernetes/pkg/features"
|
"k8s.io/kubernetes/pkg/features"
|
||||||
"k8s.io/kubernetes/pkg/proxy"
|
"k8s.io/kubernetes/pkg/proxy"
|
||||||
@ -172,7 +173,7 @@ func newServiceInfo(serviceName proxy.ServicePortName, port *api.ServicePort, se
|
|||||||
protocol: port.Protocol,
|
protocol: port.Protocol,
|
||||||
nodePort: int(port.NodePort),
|
nodePort: int(port.NodePort),
|
||||||
// Deep-copy in case the service instance changes
|
// Deep-copy in case the service instance changes
|
||||||
loadBalancerStatus: *api.LoadBalancerStatusDeepCopy(&service.Status.LoadBalancer),
|
loadBalancerStatus: *helper.LoadBalancerStatusDeepCopy(&service.Status.LoadBalancer),
|
||||||
sessionAffinityType: service.Spec.SessionAffinity,
|
sessionAffinityType: service.Spec.SessionAffinity,
|
||||||
stickyMaxAgeMinutes: 180, // TODO: paramaterize this in the API.
|
stickyMaxAgeMinutes: 180, // TODO: paramaterize this in the API.
|
||||||
externalIPs: make([]string, len(service.Spec.ExternalIPs)),
|
externalIPs: make([]string, len(service.Spec.ExternalIPs)),
|
||||||
@ -462,7 +463,7 @@ func buildNewServiceMap(allServices []*api.Service, oldServiceMap proxyServiceMa
|
|||||||
}
|
}
|
||||||
|
|
||||||
// if ClusterIP is "None" or empty, skip proxying
|
// if ClusterIP is "None" or empty, skip proxying
|
||||||
if !api.IsServiceIPSet(service) {
|
if !helper.IsServiceIPSet(service) {
|
||||||
glog.V(3).Infof("Skipping service %s due to clusterIP = %q", svcName, service.Spec.ClusterIP)
|
glog.V(3).Infof("Skipping service %s due to clusterIP = %q", svcName, service.Spec.ClusterIP)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@ go_library(
|
|||||||
tags = ["automanaged"],
|
tags = ["automanaged"],
|
||||||
deps = [
|
deps = [
|
||||||
"//pkg/api:go_default_library",
|
"//pkg/api:go_default_library",
|
||||||
|
"//pkg/api/helper:go_default_library",
|
||||||
"//pkg/proxy:go_default_library",
|
"//pkg/proxy:go_default_library",
|
||||||
"//pkg/proxy/util:go_default_library",
|
"//pkg/proxy/util:go_default_library",
|
||||||
"//pkg/util/exec:go_default_library",
|
"//pkg/util/exec:go_default_library",
|
||||||
|
@ -29,6 +29,7 @@ import (
|
|||||||
"k8s.io/apimachinery/pkg/types"
|
"k8s.io/apimachinery/pkg/types"
|
||||||
utilnet "k8s.io/apimachinery/pkg/util/net"
|
utilnet "k8s.io/apimachinery/pkg/util/net"
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
|
"k8s.io/kubernetes/pkg/api/helper"
|
||||||
"k8s.io/kubernetes/pkg/proxy"
|
"k8s.io/kubernetes/pkg/proxy"
|
||||||
|
|
||||||
utilerrors "k8s.io/apimachinery/pkg/util/errors"
|
utilerrors "k8s.io/apimachinery/pkg/util/errors"
|
||||||
@ -405,7 +406,7 @@ func (proxier *Proxier) OnServiceUpdate(services []*api.Service) {
|
|||||||
activeServices := make(map[proxy.ServicePortName]bool) // use a map as a set
|
activeServices := make(map[proxy.ServicePortName]bool) // use a map as a set
|
||||||
for _, service := range services {
|
for _, service := range services {
|
||||||
// if ClusterIP is "None" or empty, skip proxying
|
// if ClusterIP is "None" or empty, skip proxying
|
||||||
if !api.IsServiceIPSet(service) {
|
if !helper.IsServiceIPSet(service) {
|
||||||
glog.V(3).Infof("Skipping service %s due to clusterIP = %q", types.NamespacedName{Namespace: service.Namespace, Name: service.Name}, service.Spec.ClusterIP)
|
glog.V(3).Infof("Skipping service %s due to clusterIP = %q", types.NamespacedName{Namespace: service.Namespace, Name: service.Name}, service.Spec.ClusterIP)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -460,7 +461,7 @@ func (proxier *Proxier) OnServiceUpdate(services []*api.Service) {
|
|||||||
info.portal.port = int(servicePort.Port)
|
info.portal.port = int(servicePort.Port)
|
||||||
info.externalIPs = service.Spec.ExternalIPs
|
info.externalIPs = service.Spec.ExternalIPs
|
||||||
// Deep-copy in case the service instance changes
|
// Deep-copy in case the service instance changes
|
||||||
info.loadBalancerStatus = *api.LoadBalancerStatusDeepCopy(&service.Status.LoadBalancer)
|
info.loadBalancerStatus = *helper.LoadBalancerStatusDeepCopy(&service.Status.LoadBalancer)
|
||||||
info.nodePort = int(servicePort.NodePort)
|
info.nodePort = int(servicePort.NodePort)
|
||||||
info.sessionAffinityType = service.Spec.SessionAffinity
|
info.sessionAffinityType = service.Spec.SessionAffinity
|
||||||
glog.V(4).Infof("info: %#v", info)
|
glog.V(4).Infof("info: %#v", info)
|
||||||
@ -509,7 +510,7 @@ func sameConfig(info *ServiceInfo, service *api.Service, port *api.ServicePort)
|
|||||||
if !ipsEqual(info.externalIPs, service.Spec.ExternalIPs) {
|
if !ipsEqual(info.externalIPs, service.Spec.ExternalIPs) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if !api.LoadBalancerStatusEqual(&info.loadBalancerStatus, &service.Status.LoadBalancer) {
|
if !helper.LoadBalancerStatusEqual(&info.loadBalancerStatus, &service.Status.LoadBalancer) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if info.sessionAffinityType != service.Spec.SessionAffinity {
|
if info.sessionAffinityType != service.Spec.SessionAffinity {
|
||||||
|
@ -21,6 +21,7 @@ go_library(
|
|||||||
tags = ["automanaged"],
|
tags = ["automanaged"],
|
||||||
deps = [
|
deps = [
|
||||||
"//pkg/api:go_default_library",
|
"//pkg/api:go_default_library",
|
||||||
|
"//pkg/api/helper:go_default_library",
|
||||||
"//pkg/proxy:go_default_library",
|
"//pkg/proxy:go_default_library",
|
||||||
"//pkg/util/exec:go_default_library",
|
"//pkg/util/exec:go_default_library",
|
||||||
"//pkg/util/ipconfig:go_default_library",
|
"//pkg/util/ipconfig:go_default_library",
|
||||||
|
@ -30,6 +30,7 @@ import (
|
|||||||
utilnet "k8s.io/apimachinery/pkg/util/net"
|
utilnet "k8s.io/apimachinery/pkg/util/net"
|
||||||
"k8s.io/apimachinery/pkg/util/runtime"
|
"k8s.io/apimachinery/pkg/util/runtime"
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
|
"k8s.io/kubernetes/pkg/api/helper"
|
||||||
"k8s.io/kubernetes/pkg/proxy"
|
"k8s.io/kubernetes/pkg/proxy"
|
||||||
"k8s.io/kubernetes/pkg/util/netsh"
|
"k8s.io/kubernetes/pkg/util/netsh"
|
||||||
)
|
)
|
||||||
@ -322,7 +323,7 @@ func (proxier *Proxier) OnServiceUpdate(services []*api.Service) {
|
|||||||
activeServicePortPortals := make(map[ServicePortPortalName]bool) // use a map as a set
|
activeServicePortPortals := make(map[ServicePortPortalName]bool) // use a map as a set
|
||||||
for _, service := range services {
|
for _, service := range services {
|
||||||
// if ClusterIP is "None" or empty, skip proxying
|
// if ClusterIP is "None" or empty, skip proxying
|
||||||
if !api.IsServiceIPSet(service) {
|
if !helper.IsServiceIPSet(service) {
|
||||||
glog.V(3).Infof("Skipping service %s due to clusterIP = %q", types.NamespacedName{Namespace: service.Namespace, Name: service.Name}, service.Spec.ClusterIP)
|
glog.V(3).Infof("Skipping service %s due to clusterIP = %q", types.NamespacedName{Namespace: service.Namespace, Name: service.Name}, service.Spec.ClusterIP)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,7 @@ go_library(
|
|||||||
tags = ["automanaged"],
|
tags = ["automanaged"],
|
||||||
deps = [
|
deps = [
|
||||||
"//pkg/api:go_default_library",
|
"//pkg/api:go_default_library",
|
||||||
|
"//pkg/api/helper:go_default_library",
|
||||||
"//pkg/api/v1:go_default_library",
|
"//pkg/api/v1:go_default_library",
|
||||||
"//pkg/api/validation:go_default_library",
|
"//pkg/api/validation:go_default_library",
|
||||||
"//pkg/client/clientset_generated/clientset:go_default_library",
|
"//pkg/client/clientset_generated/clientset:go_default_library",
|
||||||
|
@ -27,6 +27,7 @@ import (
|
|||||||
"k8s.io/apimachinery/pkg/util/sets"
|
"k8s.io/apimachinery/pkg/util/sets"
|
||||||
"k8s.io/apiserver/pkg/admission"
|
"k8s.io/apiserver/pkg/admission"
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
|
"k8s.io/kubernetes/pkg/api/helper"
|
||||||
"k8s.io/kubernetes/pkg/api/v1"
|
"k8s.io/kubernetes/pkg/api/v1"
|
||||||
"k8s.io/kubernetes/pkg/client/clientset_generated/clientset"
|
"k8s.io/kubernetes/pkg/client/clientset_generated/clientset"
|
||||||
informers "k8s.io/kubernetes/pkg/client/informers/informers_generated/externalversions"
|
informers "k8s.io/kubernetes/pkg/client/informers/informers_generated/externalversions"
|
||||||
@ -104,7 +105,7 @@ func (p *pvcEvaluator) Constraints(required []api.ResourceName, item runtime.Obj
|
|||||||
|
|
||||||
// these are the items that we will be handling based on the objects actual storage-class
|
// these are the items that we will be handling based on the objects actual storage-class
|
||||||
pvcRequiredSet := append([]api.ResourceName{}, pvcResources...)
|
pvcRequiredSet := append([]api.ResourceName{}, pvcResources...)
|
||||||
if storageClassRef := api.GetPersistentVolumeClaimClass(pvc); len(storageClassRef) > 0 {
|
if storageClassRef := helper.GetPersistentVolumeClaimClass(pvc); len(storageClassRef) > 0 {
|
||||||
pvcRequiredSet = append(pvcRequiredSet, ResourceByStorageClass(storageClassRef, api.ResourcePersistentVolumeClaims))
|
pvcRequiredSet = append(pvcRequiredSet, ResourceByStorageClass(storageClassRef, api.ResourcePersistentVolumeClaims))
|
||||||
pvcRequiredSet = append(pvcRequiredSet, ResourceByStorageClass(storageClassRef, api.ResourceRequestsStorage))
|
pvcRequiredSet = append(pvcRequiredSet, ResourceByStorageClass(storageClassRef, api.ResourceRequestsStorage))
|
||||||
}
|
}
|
||||||
@ -175,7 +176,7 @@ func (p *pvcEvaluator) Usage(item runtime.Object) (api.ResourceList, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return result, err
|
return result, err
|
||||||
}
|
}
|
||||||
storageClassRef := api.GetPersistentVolumeClaimClass(pvc)
|
storageClassRef := helper.GetPersistentVolumeClaimClass(pvc)
|
||||||
|
|
||||||
// charge for claim
|
// charge for claim
|
||||||
result[api.ResourcePersistentVolumeClaims] = resource.MustParse("1")
|
result[api.ResourcePersistentVolumeClaims] = resource.MustParse("1")
|
||||||
|
@ -18,6 +18,7 @@ go_library(
|
|||||||
tags = ["automanaged"],
|
tags = ["automanaged"],
|
||||||
deps = [
|
deps = [
|
||||||
"//pkg/api:go_default_library",
|
"//pkg/api:go_default_library",
|
||||||
|
"//pkg/api/helper:go_default_library",
|
||||||
"//pkg/api/validation:go_default_library",
|
"//pkg/api/validation:go_default_library",
|
||||||
"//vendor:k8s.io/apimachinery/pkg/apis/meta/internalversion",
|
"//vendor:k8s.io/apimachinery/pkg/apis/meta/internalversion",
|
||||||
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
|
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
|
||||||
|
@ -34,6 +34,7 @@ import (
|
|||||||
apistorage "k8s.io/apiserver/pkg/storage"
|
apistorage "k8s.io/apiserver/pkg/storage"
|
||||||
"k8s.io/apiserver/pkg/storage/names"
|
"k8s.io/apiserver/pkg/storage/names"
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
|
"k8s.io/kubernetes/pkg/api/helper"
|
||||||
"k8s.io/kubernetes/pkg/api/validation"
|
"k8s.io/kubernetes/pkg/api/validation"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -110,7 +111,7 @@ func (rcStrategy) ValidateUpdate(ctx genericapirequest.Context, obj, old runtime
|
|||||||
updateErrorList := validation.ValidateReplicationControllerUpdate(newRc, oldRc)
|
updateErrorList := validation.ValidateReplicationControllerUpdate(newRc, oldRc)
|
||||||
errs := append(validationErrorList, updateErrorList...)
|
errs := append(validationErrorList, updateErrorList...)
|
||||||
|
|
||||||
for key, value := range api.NonConvertibleFields(oldRc.Annotations) {
|
for key, value := range helper.NonConvertibleFields(oldRc.Annotations) {
|
||||||
parts := strings.Split(key, "/")
|
parts := strings.Split(key, "/")
|
||||||
if len(parts) != 2 {
|
if len(parts) != 2 {
|
||||||
continue
|
continue
|
||||||
|
@ -20,6 +20,7 @@ go_library(
|
|||||||
tags = ["automanaged"],
|
tags = ["automanaged"],
|
||||||
deps = [
|
deps = [
|
||||||
"//pkg/api:go_default_library",
|
"//pkg/api:go_default_library",
|
||||||
|
"//pkg/api/helper:go_default_library",
|
||||||
"//pkg/api/service:go_default_library",
|
"//pkg/api/service:go_default_library",
|
||||||
"//pkg/api/validation:go_default_library",
|
"//pkg/api/validation:go_default_library",
|
||||||
"//pkg/capabilities:go_default_library",
|
"//pkg/capabilities:go_default_library",
|
||||||
|
@ -14,6 +14,7 @@ go_library(
|
|||||||
tags = ["automanaged"],
|
tags = ["automanaged"],
|
||||||
deps = [
|
deps = [
|
||||||
"//pkg/api:go_default_library",
|
"//pkg/api:go_default_library",
|
||||||
|
"//pkg/api/helper:go_default_library",
|
||||||
"//pkg/client/clientset_generated/internalclientset/typed/core/internalversion:go_default_library",
|
"//pkg/client/clientset_generated/internalclientset/typed/core/internalversion:go_default_library",
|
||||||
"//pkg/client/retry:go_default_library",
|
"//pkg/client/retry:go_default_library",
|
||||||
"//pkg/registry/core/rangeallocation:go_default_library",
|
"//pkg/registry/core/rangeallocation:go_default_library",
|
||||||
|
@ -26,6 +26,7 @@ import (
|
|||||||
"k8s.io/apimachinery/pkg/util/runtime"
|
"k8s.io/apimachinery/pkg/util/runtime"
|
||||||
"k8s.io/apimachinery/pkg/util/wait"
|
"k8s.io/apimachinery/pkg/util/wait"
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
|
"k8s.io/kubernetes/pkg/api/helper"
|
||||||
coreclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/internalversion"
|
coreclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/internalversion"
|
||||||
"k8s.io/kubernetes/pkg/client/retry"
|
"k8s.io/kubernetes/pkg/client/retry"
|
||||||
"k8s.io/kubernetes/pkg/registry/core/rangeallocation"
|
"k8s.io/kubernetes/pkg/registry/core/rangeallocation"
|
||||||
@ -128,7 +129,7 @@ func (c *Repair) runOnce() error {
|
|||||||
rebuilt := ipallocator.NewCIDRRange(c.network)
|
rebuilt := ipallocator.NewCIDRRange(c.network)
|
||||||
// Check every Service's ClusterIP, and rebuild the state as we think it should be.
|
// Check every Service's ClusterIP, and rebuild the state as we think it should be.
|
||||||
for _, svc := range list.Items {
|
for _, svc := range list.Items {
|
||||||
if !api.IsServiceIPSet(&svc) {
|
if !helper.IsServiceIPSet(&svc) {
|
||||||
// didn't need a cluster IP
|
// didn't need a cluster IP
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -37,6 +37,7 @@ import (
|
|||||||
"k8s.io/apiserver/pkg/registry/rest"
|
"k8s.io/apiserver/pkg/registry/rest"
|
||||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
|
"k8s.io/kubernetes/pkg/api/helper"
|
||||||
apiservice "k8s.io/kubernetes/pkg/api/service"
|
apiservice "k8s.io/kubernetes/pkg/api/service"
|
||||||
"k8s.io/kubernetes/pkg/api/validation"
|
"k8s.io/kubernetes/pkg/api/validation"
|
||||||
"k8s.io/kubernetes/pkg/features"
|
"k8s.io/kubernetes/pkg/features"
|
||||||
@ -87,13 +88,13 @@ func (rs *REST) Create(ctx genericapirequest.Context, obj runtime.Object) (runti
|
|||||||
releaseServiceIP := false
|
releaseServiceIP := false
|
||||||
defer func() {
|
defer func() {
|
||||||
if releaseServiceIP {
|
if releaseServiceIP {
|
||||||
if api.IsServiceIPSet(service) {
|
if helper.IsServiceIPSet(service) {
|
||||||
rs.serviceIPs.Release(net.ParseIP(service.Spec.ClusterIP))
|
rs.serviceIPs.Release(net.ParseIP(service.Spec.ClusterIP))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
if api.IsServiceIPRequested(service) {
|
if helper.IsServiceIPRequested(service) {
|
||||||
// Allocate next available.
|
// Allocate next available.
|
||||||
ip, err := rs.serviceIPs.AllocateNext()
|
ip, err := rs.serviceIPs.AllocateNext()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -104,7 +105,7 @@ func (rs *REST) Create(ctx genericapirequest.Context, obj runtime.Object) (runti
|
|||||||
}
|
}
|
||||||
service.Spec.ClusterIP = ip.String()
|
service.Spec.ClusterIP = ip.String()
|
||||||
releaseServiceIP = true
|
releaseServiceIP = true
|
||||||
} else if api.IsServiceIPSet(service) {
|
} else if helper.IsServiceIPSet(service) {
|
||||||
// Try to respect the requested IP.
|
// Try to respect the requested IP.
|
||||||
if err := rs.serviceIPs.Allocate(net.ParseIP(service.Spec.ClusterIP)); err != nil {
|
if err := rs.serviceIPs.Allocate(net.ParseIP(service.Spec.ClusterIP)); err != nil {
|
||||||
// TODO: when validation becomes versioned, this gets more complicated.
|
// TODO: when validation becomes versioned, this gets more complicated.
|
||||||
@ -226,7 +227,7 @@ func (rs *REST) Delete(ctx genericapirequest.Context, id string) (runtime.Object
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if api.IsServiceIPSet(service) {
|
if helper.IsServiceIPSet(service) {
|
||||||
rs.serviceIPs.Release(net.ParseIP(service.Spec.ClusterIP))
|
rs.serviceIPs.Release(net.ParseIP(service.Spec.ClusterIP))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ go_test(
|
|||||||
library = ":go_default_library",
|
library = ":go_default_library",
|
||||||
tags = ["automanaged"],
|
tags = ["automanaged"],
|
||||||
deps = [
|
deps = [
|
||||||
"//pkg/api:go_default_library",
|
"//pkg/api/helper:go_default_library",
|
||||||
"//pkg/apis/rbac:go_default_library",
|
"//pkg/apis/rbac:go_default_library",
|
||||||
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
|
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
|
||||||
],
|
],
|
||||||
|
@ -20,7 +20,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api/helper"
|
||||||
"k8s.io/kubernetes/pkg/apis/rbac"
|
"k8s.io/kubernetes/pkg/apis/rbac"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -268,7 +268,7 @@ func TestComputeReconciledRole(t *testing.T) {
|
|||||||
t.Errorf("%s: Expected\n\t%v\ngot\n\t%v", k, tc.expectedReconciliationNeeded, reconciliationNeeded)
|
t.Errorf("%s: Expected\n\t%v\ngot\n\t%v", k, tc.expectedReconciliationNeeded, reconciliationNeeded)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if reconciliationNeeded && !api.Semantic.DeepEqual(result.Role.(ClusterRoleRuleOwner).ClusterRole, tc.expectedReconciledRole) {
|
if reconciliationNeeded && !helper.Semantic.DeepEqual(result.Role.(ClusterRoleRuleOwner).ClusterRole, tc.expectedReconciledRole) {
|
||||||
t.Errorf("%s: Expected\n\t%#v\ngot\n\t%#v", k, tc.expectedReconciledRole, result.Role)
|
t.Errorf("%s: Expected\n\t%#v\ngot\n\t%#v", k, tc.expectedReconciledRole, result.Role)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@ package reconciliation
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
api "k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api/helper"
|
||||||
"k8s.io/kubernetes/pkg/apis/rbac"
|
"k8s.io/kubernetes/pkg/apis/rbac"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -81,10 +81,10 @@ func TestDiffObjectReferenceLists(t *testing.T) {
|
|||||||
|
|
||||||
for k, tc := range tests {
|
for k, tc := range tests {
|
||||||
onlyA, onlyB := diffSubjectLists(tc.A, tc.B)
|
onlyA, onlyB := diffSubjectLists(tc.A, tc.B)
|
||||||
if !api.Semantic.DeepEqual(onlyA, tc.ExpectedOnlyA) {
|
if !helper.Semantic.DeepEqual(onlyA, tc.ExpectedOnlyA) {
|
||||||
t.Errorf("%s: Expected %#v, got %#v", k, tc.ExpectedOnlyA, onlyA)
|
t.Errorf("%s: Expected %#v, got %#v", k, tc.ExpectedOnlyA, onlyA)
|
||||||
}
|
}
|
||||||
if !api.Semantic.DeepEqual(onlyB, tc.ExpectedOnlyB) {
|
if !helper.Semantic.DeepEqual(onlyB, tc.ExpectedOnlyB) {
|
||||||
t.Errorf("%s: Expected %#v, got %#v", k, tc.ExpectedOnlyB, onlyB)
|
t.Errorf("%s: Expected %#v, got %#v", k, tc.ExpectedOnlyB, onlyB)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -174,7 +174,7 @@ func TestComputeUpdate(t *testing.T) {
|
|||||||
t.Errorf("%s: Expected\n\t%v\ngot\n\t%v (%v)", k, tc.ExpectedUpdateNeeded, updateNeeded, result.Operation)
|
t.Errorf("%s: Expected\n\t%v\ngot\n\t%v (%v)", k, tc.ExpectedUpdateNeeded, updateNeeded, result.Operation)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if updateNeeded && !api.Semantic.DeepEqual(updatedBinding, tc.ExpectedUpdatedBinding) {
|
if updateNeeded && !helper.Semantic.DeepEqual(updatedBinding, tc.ExpectedUpdatedBinding) {
|
||||||
t.Errorf("%s: Expected\n\t%v %v\ngot\n\t%v %v", k, tc.ExpectedUpdatedBinding.RoleRef, tc.ExpectedUpdatedBinding.Subjects, updatedBinding.RoleRef, updatedBinding.Subjects)
|
t.Errorf("%s: Expected\n\t%v %v\ngot\n\t%v %v", k, tc.ExpectedUpdatedBinding.RoleRef, tc.ExpectedUpdatedBinding.Subjects, updatedBinding.RoleRef, updatedBinding.Subjects)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,7 @@ go_library(
|
|||||||
tags = ["automanaged"],
|
tags = ["automanaged"],
|
||||||
deps = [
|
deps = [
|
||||||
"//pkg/api:go_default_library",
|
"//pkg/api:go_default_library",
|
||||||
|
"//pkg/api/helper:go_default_library",
|
||||||
"//vendor:k8s.io/apimachinery/pkg/util/validation/field",
|
"//vendor:k8s.io/apimachinery/pkg/util/validation/field",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
@ -26,7 +27,10 @@ go_test(
|
|||||||
srcs = ["mustmatchpatterns_test.go"],
|
srcs = ["mustmatchpatterns_test.go"],
|
||||||
library = ":go_default_library",
|
library = ":go_default_library",
|
||||||
tags = ["automanaged"],
|
tags = ["automanaged"],
|
||||||
deps = ["//pkg/api:go_default_library"],
|
deps = [
|
||||||
|
"//pkg/api:go_default_library",
|
||||||
|
"//pkg/api/helper:go_default_library",
|
||||||
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
filegroup(
|
filegroup(
|
||||||
|
@ -22,6 +22,7 @@ import (
|
|||||||
|
|
||||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
|
"k8s.io/kubernetes/pkg/api/helper"
|
||||||
)
|
)
|
||||||
|
|
||||||
// mustMatchPatterns implements the CapabilitiesStrategy interface
|
// mustMatchPatterns implements the CapabilitiesStrategy interface
|
||||||
@ -59,7 +60,7 @@ func (s *mustMatchPatterns) validateAnnotation(pod *api.Pod, key string) field.E
|
|||||||
|
|
||||||
fieldPath := field.NewPath("pod", "metadata", "annotations").Key(key)
|
fieldPath := field.NewPath("pod", "metadata", "annotations").Key(key)
|
||||||
|
|
||||||
sysctls, err := api.SysctlsFromPodAnnotation(pod.Annotations[key])
|
sysctls, err := helper.SysctlsFromPodAnnotation(pod.Annotations[key])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
allErrs = append(allErrs, field.Invalid(fieldPath, pod.Annotations[key], err.Error()))
|
allErrs = append(allErrs, field.Invalid(fieldPath, pod.Annotations[key], err.Error()))
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
|
"k8s.io/kubernetes/pkg/api/helper"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestValidate(t *testing.T) {
|
func TestValidate(t *testing.T) {
|
||||||
@ -75,7 +76,7 @@ func TestValidate(t *testing.T) {
|
|||||||
}
|
}
|
||||||
testAllowed := func(key string, category string) {
|
testAllowed := func(key string, category string) {
|
||||||
pod.Annotations = map[string]string{
|
pod.Annotations = map[string]string{
|
||||||
key: api.PodAnnotationsFromSysctls(sysctls),
|
key: helper.PodAnnotationsFromSysctls(sysctls),
|
||||||
}
|
}
|
||||||
errs = strategy.Validate(pod)
|
errs = strategy.Validate(pod)
|
||||||
if len(errs) != 0 {
|
if len(errs) != 0 {
|
||||||
@ -85,7 +86,7 @@ func TestValidate(t *testing.T) {
|
|||||||
testDisallowed := func(key string, category string) {
|
testDisallowed := func(key string, category string) {
|
||||||
for _, s := range v.disallowed {
|
for _, s := range v.disallowed {
|
||||||
pod.Annotations = map[string]string{
|
pod.Annotations = map[string]string{
|
||||||
key: api.PodAnnotationsFromSysctls([]api.Sysctl{{Name: s, Value: "dummy"}}),
|
key: helper.PodAnnotationsFromSysctls([]api.Sysctl{{Name: s, Value: "dummy"}}),
|
||||||
}
|
}
|
||||||
errs = strategy.Validate(pod)
|
errs = strategy.Validate(pod)
|
||||||
if len(errs) == 0 {
|
if len(errs) == 0 {
|
||||||
|
@ -15,6 +15,7 @@ go_test(
|
|||||||
tags = ["automanaged"],
|
tags = ["automanaged"],
|
||||||
deps = [
|
deps = [
|
||||||
"//pkg/api:go_default_library",
|
"//pkg/api:go_default_library",
|
||||||
|
"//pkg/api/helper:go_default_library",
|
||||||
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
|
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
|
||||||
"//vendor:k8s.io/apiserver/pkg/admission",
|
"//vendor:k8s.io/apiserver/pkg/admission",
|
||||||
],
|
],
|
||||||
@ -26,6 +27,7 @@ go_library(
|
|||||||
tags = ["automanaged"],
|
tags = ["automanaged"],
|
||||||
deps = [
|
deps = [
|
||||||
"//pkg/api:go_default_library",
|
"//pkg/api:go_default_library",
|
||||||
|
"//pkg/api/helper:go_default_library",
|
||||||
"//vendor:k8s.io/apimachinery/pkg/api/errors",
|
"//vendor:k8s.io/apimachinery/pkg/api/errors",
|
||||||
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
|
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
|
||||||
"//vendor:k8s.io/apiserver/pkg/admission",
|
"//vendor:k8s.io/apiserver/pkg/admission",
|
||||||
|
@ -25,6 +25,7 @@ import (
|
|||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apiserver/pkg/admission"
|
"k8s.io/apiserver/pkg/admission"
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
|
"k8s.io/kubernetes/pkg/api/helper"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -97,7 +98,7 @@ func (p *plugin) Admit(attributes admission.Attributes) (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !toleratesNodeNotReady {
|
if !toleratesNodeNotReady {
|
||||||
api.AddOrUpdateTolerationInPod(pod, &api.Toleration{
|
helper.AddOrUpdateTolerationInPod(pod, &api.Toleration{
|
||||||
Key: metav1.TaintNodeNotReady,
|
Key: metav1.TaintNodeNotReady,
|
||||||
Operator: api.TolerationOpExists,
|
Operator: api.TolerationOpExists,
|
||||||
Effect: api.TaintEffectNoExecute,
|
Effect: api.TaintEffectNoExecute,
|
||||||
@ -106,7 +107,7 @@ func (p *plugin) Admit(attributes admission.Attributes) (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !toleratesNodeUnreachable {
|
if !toleratesNodeUnreachable {
|
||||||
api.AddOrUpdateTolerationInPod(pod, &api.Toleration{
|
helper.AddOrUpdateTolerationInPod(pod, &api.Toleration{
|
||||||
Key: metav1.TaintNodeUnreachable,
|
Key: metav1.TaintNodeUnreachable,
|
||||||
Operator: api.TolerationOpExists,
|
Operator: api.TolerationOpExists,
|
||||||
Effect: api.TaintEffectNoExecute,
|
Effect: api.TaintEffectNoExecute,
|
||||||
|
@ -22,6 +22,7 @@ import (
|
|||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apiserver/pkg/admission"
|
"k8s.io/apiserver/pkg/admission"
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
|
"k8s.io/kubernetes/pkg/api/helper"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestForgivenessAdmission(t *testing.T) {
|
func TestForgivenessAdmission(t *testing.T) {
|
||||||
@ -266,7 +267,7 @@ func TestForgivenessAdmission(t *testing.T) {
|
|||||||
t.Errorf("[%s]: unexpected error %v for pod %+v", test.description, err, test.requestedPod)
|
t.Errorf("[%s]: unexpected error %v for pod %+v", test.description, err, test.requestedPod)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !api.Semantic.DeepEqual(test.expectedPod.Annotations, test.requestedPod.Annotations) {
|
if !helper.Semantic.DeepEqual(test.expectedPod.Annotations, test.requestedPod.Annotations) {
|
||||||
t.Errorf("[%s]: expected %#v got %#v", test.description, test.expectedPod.Annotations, test.requestedPod.Annotations)
|
t.Errorf("[%s]: expected %#v got %#v", test.description, test.expectedPod.Annotations, test.requestedPod.Annotations)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -39,6 +39,7 @@ go_test(
|
|||||||
tags = ["automanaged"],
|
tags = ["automanaged"],
|
||||||
deps = [
|
deps = [
|
||||||
"//pkg/api:go_default_library",
|
"//pkg/api:go_default_library",
|
||||||
|
"//pkg/api/helper:go_default_library",
|
||||||
"//pkg/apis/extensions:go_default_library",
|
"//pkg/apis/extensions:go_default_library",
|
||||||
"//pkg/client/informers/informers_generated/internalversion:go_default_library",
|
"//pkg/client/informers/informers_generated/internalversion:go_default_library",
|
||||||
"//pkg/client/listers/extensions/internalversion:go_default_library",
|
"//pkg/client/listers/extensions/internalversion:go_default_library",
|
||||||
|
@ -31,6 +31,7 @@ import (
|
|||||||
"k8s.io/apiserver/pkg/authentication/user"
|
"k8s.io/apiserver/pkg/authentication/user"
|
||||||
"k8s.io/apiserver/pkg/authorization/authorizer"
|
"k8s.io/apiserver/pkg/authorization/authorizer"
|
||||||
kapi "k8s.io/kubernetes/pkg/api"
|
kapi "k8s.io/kubernetes/pkg/api"
|
||||||
|
"k8s.io/kubernetes/pkg/api/helper"
|
||||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||||
informers "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion"
|
informers "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion"
|
||||||
extensionslisters "k8s.io/kubernetes/pkg/client/listers/extensions/internalversion"
|
extensionslisters "k8s.io/kubernetes/pkg/client/listers/extensions/internalversion"
|
||||||
@ -1172,8 +1173,8 @@ func TestAdmitSysctls(t *testing.T) {
|
|||||||
}
|
}
|
||||||
return sysctls
|
return sysctls
|
||||||
}
|
}
|
||||||
pod.Annotations[kapi.SysctlsPodAnnotationKey] = kapi.PodAnnotationsFromSysctls(dummySysctls(safeSysctls))
|
pod.Annotations[kapi.SysctlsPodAnnotationKey] = helper.PodAnnotationsFromSysctls(dummySysctls(safeSysctls))
|
||||||
pod.Annotations[kapi.UnsafeSysctlsPodAnnotationKey] = kapi.PodAnnotationsFromSysctls(dummySysctls(unsafeSysctls))
|
pod.Annotations[kapi.UnsafeSysctlsPodAnnotationKey] = helper.PodAnnotationsFromSysctls(dummySysctls(unsafeSysctls))
|
||||||
return pod
|
return pod
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1319,7 +1320,7 @@ func TestAdmitSysctls(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for k, v := range tests {
|
for k, v := range tests {
|
||||||
origSafeSysctls, origUnsafeSysctls, err := kapi.SysctlsFromPodAnnotations(v.pod.Annotations)
|
origSafeSysctls, origUnsafeSysctls, err := helper.SysctlsFromPodAnnotations(v.pod.Annotations)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("invalid sysctl annotation: %v", err)
|
t.Fatalf("invalid sysctl annotation: %v", err)
|
||||||
}
|
}
|
||||||
@ -1327,7 +1328,7 @@ func TestAdmitSysctls(t *testing.T) {
|
|||||||
testPSPAdmit(k, v.psps, v.pod, v.shouldPass, v.expectedPSP, t)
|
testPSPAdmit(k, v.psps, v.pod, v.shouldPass, v.expectedPSP, t)
|
||||||
|
|
||||||
if v.shouldPass {
|
if v.shouldPass {
|
||||||
safeSysctls, unsafeSysctls, _ := kapi.SysctlsFromPodAnnotations(v.pod.Annotations)
|
safeSysctls, unsafeSysctls, _ := helper.SysctlsFromPodAnnotations(v.pod.Annotations)
|
||||||
if !reflect.DeepEqual(safeSysctls, origSafeSysctls) {
|
if !reflect.DeepEqual(safeSysctls, origSafeSysctls) {
|
||||||
t.Errorf("%s: wrong safe sysctls: expected=%v, got=%v", k, origSafeSysctls, safeSysctls)
|
t.Errorf("%s: wrong safe sysctls: expected=%v, got=%v", k, origSafeSysctls, safeSysctls)
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,7 @@ go_library(
|
|||||||
tags = ["automanaged"],
|
tags = ["automanaged"],
|
||||||
deps = [
|
deps = [
|
||||||
"//pkg/api:go_default_library",
|
"//pkg/api:go_default_library",
|
||||||
|
"//pkg/api/helper:go_default_library",
|
||||||
"//pkg/apis/storage:go_default_library",
|
"//pkg/apis/storage:go_default_library",
|
||||||
"//pkg/apis/storage/util:go_default_library",
|
"//pkg/apis/storage/util:go_default_library",
|
||||||
"//pkg/client/informers/informers_generated/internalversion:go_default_library",
|
"//pkg/client/informers/informers_generated/internalversion:go_default_library",
|
||||||
|
@ -26,6 +26,7 @@ import (
|
|||||||
"k8s.io/apimachinery/pkg/labels"
|
"k8s.io/apimachinery/pkg/labels"
|
||||||
admission "k8s.io/apiserver/pkg/admission"
|
admission "k8s.io/apiserver/pkg/admission"
|
||||||
api "k8s.io/kubernetes/pkg/api"
|
api "k8s.io/kubernetes/pkg/api"
|
||||||
|
"k8s.io/kubernetes/pkg/api/helper"
|
||||||
"k8s.io/kubernetes/pkg/apis/storage"
|
"k8s.io/kubernetes/pkg/apis/storage"
|
||||||
storageutil "k8s.io/kubernetes/pkg/apis/storage/util"
|
storageutil "k8s.io/kubernetes/pkg/apis/storage/util"
|
||||||
informers "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion"
|
informers "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion"
|
||||||
@ -96,7 +97,7 @@ func (c *claimDefaulterPlugin) Admit(a admission.Attributes) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if api.PersistentVolumeClaimHasClass(pvc) {
|
if helper.PersistentVolumeClaimHasClass(pvc) {
|
||||||
// The user asked for a class.
|
// The user asked for a class.
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -64,4 +64,7 @@ const (
|
|||||||
// in the Annotations of a Pod.
|
// in the Annotations of a Pod.
|
||||||
// TODO: remove when alpha support for affinity is removed
|
// TODO: remove when alpha support for affinity is removed
|
||||||
AffinityAnnotationKey string = "scheduler.alpha.kubernetes.io/affinity"
|
AffinityAnnotationKey string = "scheduler.alpha.kubernetes.io/affinity"
|
||||||
|
|
||||||
|
// annotation key prefix used to identify non-convertible json paths.
|
||||||
|
NonConvertibleAnnotationPrefix = "non-convertible.kubernetes.io"
|
||||||
)
|
)
|
||||||
|
@ -14,18 +14,15 @@ See the License for the specific language governing permissions and
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package api
|
package helper
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/md5"
|
"crypto/md5"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"reflect"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/davecgh/go-spew/spew"
|
|
||||||
|
|
||||||
"k8s.io/apimachinery/pkg/api/resource"
|
"k8s.io/apimachinery/pkg/api/resource"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/conversion"
|
"k8s.io/apimachinery/pkg/conversion"
|
||||||
@ -34,25 +31,7 @@ import (
|
|||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
"k8s.io/apimachinery/pkg/selection"
|
"k8s.io/apimachinery/pkg/selection"
|
||||||
"k8s.io/apimachinery/pkg/util/sets"
|
"k8s.io/apimachinery/pkg/util/sets"
|
||||||
)
|
"k8s.io/client-go/pkg/api"
|
||||||
|
|
||||||
// Conversion error conveniently packages up errors in conversions.
|
|
||||||
type ConversionError struct {
|
|
||||||
In, Out interface{}
|
|
||||||
Message string
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return a helpful string about the error
|
|
||||||
func (c *ConversionError) Error() string {
|
|
||||||
return spew.Sprintf(
|
|
||||||
"Conversion error: %s. (in: %v(%+v) out: %v)",
|
|
||||||
c.Message, reflect.TypeOf(c.In), c.In, reflect.TypeOf(c.Out),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
|
||||||
// annotation key prefix used to identify non-convertible json paths.
|
|
||||||
NonConvertibleAnnotationPrefix = "non-convertible.kubernetes.io"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// NonConvertibleFields iterates over the provided map and filters out all but
|
// NonConvertibleFields iterates over the provided map and filters out all but
|
||||||
@ -60,7 +39,7 @@ const (
|
|||||||
func NonConvertibleFields(annotations map[string]string) map[string]string {
|
func NonConvertibleFields(annotations map[string]string) map[string]string {
|
||||||
nonConvertibleKeys := map[string]string{}
|
nonConvertibleKeys := map[string]string{}
|
||||||
for key, value := range annotations {
|
for key, value := range annotations {
|
||||||
if strings.HasPrefix(key, NonConvertibleAnnotationPrefix) {
|
if strings.HasPrefix(key, api.NonConvertibleAnnotationPrefix) {
|
||||||
nonConvertibleKeys[key] = value
|
nonConvertibleKeys[key] = value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -89,10 +68,10 @@ var Semantic = conversion.EqualitiesOrDie(
|
|||||||
)
|
)
|
||||||
|
|
||||||
var standardResourceQuotaScopes = sets.NewString(
|
var standardResourceQuotaScopes = sets.NewString(
|
||||||
string(ResourceQuotaScopeTerminating),
|
string(api.ResourceQuotaScopeTerminating),
|
||||||
string(ResourceQuotaScopeNotTerminating),
|
string(api.ResourceQuotaScopeNotTerminating),
|
||||||
string(ResourceQuotaScopeBestEffort),
|
string(api.ResourceQuotaScopeBestEffort),
|
||||||
string(ResourceQuotaScopeNotBestEffort),
|
string(api.ResourceQuotaScopeNotBestEffort),
|
||||||
)
|
)
|
||||||
|
|
||||||
// IsStandardResourceQuotaScope returns true if the scope is a standard value
|
// IsStandardResourceQuotaScope returns true if the scope is a standard value
|
||||||
@ -101,24 +80,24 @@ func IsStandardResourceQuotaScope(str string) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var podObjectCountQuotaResources = sets.NewString(
|
var podObjectCountQuotaResources = sets.NewString(
|
||||||
string(ResourcePods),
|
string(api.ResourcePods),
|
||||||
)
|
)
|
||||||
|
|
||||||
var podComputeQuotaResources = sets.NewString(
|
var podComputeQuotaResources = sets.NewString(
|
||||||
string(ResourceCPU),
|
string(api.ResourceCPU),
|
||||||
string(ResourceMemory),
|
string(api.ResourceMemory),
|
||||||
string(ResourceLimitsCPU),
|
string(api.ResourceLimitsCPU),
|
||||||
string(ResourceLimitsMemory),
|
string(api.ResourceLimitsMemory),
|
||||||
string(ResourceRequestsCPU),
|
string(api.ResourceRequestsCPU),
|
||||||
string(ResourceRequestsMemory),
|
string(api.ResourceRequestsMemory),
|
||||||
)
|
)
|
||||||
|
|
||||||
// IsResourceQuotaScopeValidForResource returns true if the resource applies to the specified scope
|
// IsResourceQuotaScopeValidForResource returns true if the resource applies to the specified scope
|
||||||
func IsResourceQuotaScopeValidForResource(scope ResourceQuotaScope, resource string) bool {
|
func IsResourceQuotaScopeValidForResource(scope api.ResourceQuotaScope, resource string) bool {
|
||||||
switch scope {
|
switch scope {
|
||||||
case ResourceQuotaScopeTerminating, ResourceQuotaScopeNotTerminating, ResourceQuotaScopeNotBestEffort:
|
case api.ResourceQuotaScopeTerminating, api.ResourceQuotaScopeNotTerminating, api.ResourceQuotaScopeNotBestEffort:
|
||||||
return podObjectCountQuotaResources.Has(resource) || podComputeQuotaResources.Has(resource)
|
return podObjectCountQuotaResources.Has(resource) || podComputeQuotaResources.Has(resource)
|
||||||
case ResourceQuotaScopeBestEffort:
|
case api.ResourceQuotaScopeBestEffort:
|
||||||
return podObjectCountQuotaResources.Has(resource)
|
return podObjectCountQuotaResources.Has(resource)
|
||||||
default:
|
default:
|
||||||
return true
|
return true
|
||||||
@ -126,8 +105,8 @@ func IsResourceQuotaScopeValidForResource(scope ResourceQuotaScope, resource str
|
|||||||
}
|
}
|
||||||
|
|
||||||
var standardContainerResources = sets.NewString(
|
var standardContainerResources = sets.NewString(
|
||||||
string(ResourceCPU),
|
string(api.ResourceCPU),
|
||||||
string(ResourceMemory),
|
string(api.ResourceMemory),
|
||||||
)
|
)
|
||||||
|
|
||||||
// IsStandardContainerResourceName returns true if the container can make a resource request
|
// IsStandardContainerResourceName returns true if the container can make a resource request
|
||||||
@ -138,24 +117,24 @@ func IsStandardContainerResourceName(str string) bool {
|
|||||||
|
|
||||||
// IsOpaqueIntResourceName returns true if the resource name has the opaque
|
// IsOpaqueIntResourceName returns true if the resource name has the opaque
|
||||||
// integer resource prefix.
|
// integer resource prefix.
|
||||||
func IsOpaqueIntResourceName(name ResourceName) bool {
|
func IsOpaqueIntResourceName(name api.ResourceName) bool {
|
||||||
return strings.HasPrefix(string(name), ResourceOpaqueIntPrefix)
|
return strings.HasPrefix(string(name), api.ResourceOpaqueIntPrefix)
|
||||||
}
|
}
|
||||||
|
|
||||||
// OpaqueIntResourceName returns a ResourceName with the canonical opaque
|
// OpaqueIntResourceName returns a ResourceName with the canonical opaque
|
||||||
// integer prefix prepended. If the argument already has the prefix, it is
|
// integer prefix prepended. If the argument already has the prefix, it is
|
||||||
// returned unmodified.
|
// returned unmodified.
|
||||||
func OpaqueIntResourceName(name string) ResourceName {
|
func OpaqueIntResourceName(name string) api.ResourceName {
|
||||||
if IsOpaqueIntResourceName(ResourceName(name)) {
|
if IsOpaqueIntResourceName(api.ResourceName(name)) {
|
||||||
return ResourceName(name)
|
return api.ResourceName(name)
|
||||||
}
|
}
|
||||||
return ResourceName(fmt.Sprintf("%s%s", ResourceOpaqueIntPrefix, name))
|
return api.ResourceName(fmt.Sprintf("%s%s", api.ResourceOpaqueIntPrefix, name))
|
||||||
}
|
}
|
||||||
|
|
||||||
var standardLimitRangeTypes = sets.NewString(
|
var standardLimitRangeTypes = sets.NewString(
|
||||||
string(LimitTypePod),
|
string(api.LimitTypePod),
|
||||||
string(LimitTypeContainer),
|
string(api.LimitTypeContainer),
|
||||||
string(LimitTypePersistentVolumeClaim),
|
string(api.LimitTypePersistentVolumeClaim),
|
||||||
)
|
)
|
||||||
|
|
||||||
// IsStandardLimitRangeType returns true if the type is Pod or Container
|
// IsStandardLimitRangeType returns true if the type is Pod or Container
|
||||||
@ -164,22 +143,22 @@ func IsStandardLimitRangeType(str string) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var standardQuotaResources = sets.NewString(
|
var standardQuotaResources = sets.NewString(
|
||||||
string(ResourceCPU),
|
string(api.ResourceCPU),
|
||||||
string(ResourceMemory),
|
string(api.ResourceMemory),
|
||||||
string(ResourceRequestsCPU),
|
string(api.ResourceRequestsCPU),
|
||||||
string(ResourceRequestsMemory),
|
string(api.ResourceRequestsMemory),
|
||||||
string(ResourceRequestsStorage),
|
string(api.ResourceRequestsStorage),
|
||||||
string(ResourceLimitsCPU),
|
string(api.ResourceLimitsCPU),
|
||||||
string(ResourceLimitsMemory),
|
string(api.ResourceLimitsMemory),
|
||||||
string(ResourcePods),
|
string(api.ResourcePods),
|
||||||
string(ResourceQuotas),
|
string(api.ResourceQuotas),
|
||||||
string(ResourceServices),
|
string(api.ResourceServices),
|
||||||
string(ResourceReplicationControllers),
|
string(api.ResourceReplicationControllers),
|
||||||
string(ResourceSecrets),
|
string(api.ResourceSecrets),
|
||||||
string(ResourcePersistentVolumeClaims),
|
string(api.ResourcePersistentVolumeClaims),
|
||||||
string(ResourceConfigMaps),
|
string(api.ResourceConfigMaps),
|
||||||
string(ResourceServicesNodePorts),
|
string(api.ResourceServicesNodePorts),
|
||||||
string(ResourceServicesLoadBalancers),
|
string(api.ResourceServicesLoadBalancers),
|
||||||
)
|
)
|
||||||
|
|
||||||
// IsStandardQuotaResourceName returns true if the resource is known to
|
// IsStandardQuotaResourceName returns true if the resource is known to
|
||||||
@ -189,21 +168,21 @@ func IsStandardQuotaResourceName(str string) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var standardResources = sets.NewString(
|
var standardResources = sets.NewString(
|
||||||
string(ResourceCPU),
|
string(api.ResourceCPU),
|
||||||
string(ResourceMemory),
|
string(api.ResourceMemory),
|
||||||
string(ResourceRequestsCPU),
|
string(api.ResourceRequestsCPU),
|
||||||
string(ResourceRequestsMemory),
|
string(api.ResourceRequestsMemory),
|
||||||
string(ResourceLimitsCPU),
|
string(api.ResourceLimitsCPU),
|
||||||
string(ResourceLimitsMemory),
|
string(api.ResourceLimitsMemory),
|
||||||
string(ResourcePods),
|
string(api.ResourcePods),
|
||||||
string(ResourceQuotas),
|
string(api.ResourceQuotas),
|
||||||
string(ResourceServices),
|
string(api.ResourceServices),
|
||||||
string(ResourceReplicationControllers),
|
string(api.ResourceReplicationControllers),
|
||||||
string(ResourceSecrets),
|
string(api.ResourceSecrets),
|
||||||
string(ResourceConfigMaps),
|
string(api.ResourceConfigMaps),
|
||||||
string(ResourcePersistentVolumeClaims),
|
string(api.ResourcePersistentVolumeClaims),
|
||||||
string(ResourceStorage),
|
string(api.ResourceStorage),
|
||||||
string(ResourceRequestsStorage),
|
string(api.ResourceRequestsStorage),
|
||||||
)
|
)
|
||||||
|
|
||||||
// IsStandardResourceName returns true if the resource is known to the system
|
// IsStandardResourceName returns true if the resource is known to the system
|
||||||
@ -212,50 +191,50 @@ func IsStandardResourceName(str string) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var integerResources = sets.NewString(
|
var integerResources = sets.NewString(
|
||||||
string(ResourcePods),
|
string(api.ResourcePods),
|
||||||
string(ResourceQuotas),
|
string(api.ResourceQuotas),
|
||||||
string(ResourceServices),
|
string(api.ResourceServices),
|
||||||
string(ResourceReplicationControllers),
|
string(api.ResourceReplicationControllers),
|
||||||
string(ResourceSecrets),
|
string(api.ResourceSecrets),
|
||||||
string(ResourceConfigMaps),
|
string(api.ResourceConfigMaps),
|
||||||
string(ResourcePersistentVolumeClaims),
|
string(api.ResourcePersistentVolumeClaims),
|
||||||
string(ResourceServicesNodePorts),
|
string(api.ResourceServicesNodePorts),
|
||||||
string(ResourceServicesLoadBalancers),
|
string(api.ResourceServicesLoadBalancers),
|
||||||
)
|
)
|
||||||
|
|
||||||
// IsIntegerResourceName returns true if the resource is measured in integer values
|
// IsIntegerResourceName returns true if the resource is measured in integer values
|
||||||
func IsIntegerResourceName(str string) bool {
|
func IsIntegerResourceName(str string) bool {
|
||||||
return integerResources.Has(str) || IsOpaqueIntResourceName(ResourceName(str))
|
return integerResources.Has(str) || IsOpaqueIntResourceName(api.ResourceName(str))
|
||||||
}
|
}
|
||||||
|
|
||||||
// this function aims to check if the service's ClusterIP is set or not
|
// this function aims to check if the service's ClusterIP is set or not
|
||||||
// the objective is not to perform validation here
|
// the objective is not to perform validation here
|
||||||
func IsServiceIPSet(service *Service) bool {
|
func IsServiceIPSet(service *api.Service) bool {
|
||||||
return service.Spec.ClusterIP != ClusterIPNone && service.Spec.ClusterIP != ""
|
return service.Spec.ClusterIP != api.ClusterIPNone && service.Spec.ClusterIP != ""
|
||||||
}
|
}
|
||||||
|
|
||||||
// this function aims to check if the service's cluster IP is requested or not
|
// this function aims to check if the service's cluster IP is requested or not
|
||||||
func IsServiceIPRequested(service *Service) bool {
|
func IsServiceIPRequested(service *api.Service) bool {
|
||||||
// ExternalName services are CNAME aliases to external ones. Ignore the IP.
|
// ExternalName services are CNAME aliases to external ones. Ignore the IP.
|
||||||
if service.Spec.Type == ServiceTypeExternalName {
|
if service.Spec.Type == api.ServiceTypeExternalName {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return service.Spec.ClusterIP == ""
|
return service.Spec.ClusterIP == ""
|
||||||
}
|
}
|
||||||
|
|
||||||
var standardFinalizers = sets.NewString(
|
var standardFinalizers = sets.NewString(
|
||||||
string(FinalizerKubernetes),
|
string(api.FinalizerKubernetes),
|
||||||
metav1.FinalizerOrphanDependents,
|
metav1.FinalizerOrphanDependents,
|
||||||
)
|
)
|
||||||
|
|
||||||
// HasAnnotation returns a bool if passed in annotation exists
|
// HasAnnotation returns a bool if passed in annotation exists
|
||||||
func HasAnnotation(obj ObjectMeta, ann string) bool {
|
func HasAnnotation(obj api.ObjectMeta, ann string) bool {
|
||||||
_, found := obj.Annotations[ann]
|
_, found := obj.Annotations[ann]
|
||||||
return found
|
return found
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetMetaDataAnnotation sets the annotation and value
|
// SetMetaDataAnnotation sets the annotation and value
|
||||||
func SetMetaDataAnnotation(obj *ObjectMeta, ann string, value string) {
|
func SetMetaDataAnnotation(obj *api.ObjectMeta, ann string, value string) {
|
||||||
if obj.Annotations == nil {
|
if obj.Annotations == nil {
|
||||||
obj.Annotations = make(map[string]string)
|
obj.Annotations = make(map[string]string)
|
||||||
}
|
}
|
||||||
@ -268,7 +247,7 @@ func IsStandardFinalizerName(str string) bool {
|
|||||||
|
|
||||||
// AddToNodeAddresses appends the NodeAddresses to the passed-by-pointer slice,
|
// AddToNodeAddresses appends the NodeAddresses to the passed-by-pointer slice,
|
||||||
// only if they do not already exist
|
// only if they do not already exist
|
||||||
func AddToNodeAddresses(addresses *[]NodeAddress, addAddresses ...NodeAddress) {
|
func AddToNodeAddresses(addresses *[]api.NodeAddress, addAddresses ...api.NodeAddress) {
|
||||||
for _, add := range addAddresses {
|
for _, add := range addAddresses {
|
||||||
exists := false
|
exists := false
|
||||||
for _, existing := range *addresses {
|
for _, existing := range *addresses {
|
||||||
@ -292,11 +271,11 @@ func HashObject(obj runtime.Object, codec runtime.Codec) (string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: make method on LoadBalancerStatus?
|
// TODO: make method on LoadBalancerStatus?
|
||||||
func LoadBalancerStatusEqual(l, r *LoadBalancerStatus) bool {
|
func LoadBalancerStatusEqual(l, r *api.LoadBalancerStatus) bool {
|
||||||
return ingressSliceEqual(l.Ingress, r.Ingress)
|
return ingressSliceEqual(l.Ingress, r.Ingress)
|
||||||
}
|
}
|
||||||
|
|
||||||
func ingressSliceEqual(lhs, rhs []LoadBalancerIngress) bool {
|
func ingressSliceEqual(lhs, rhs []api.LoadBalancerIngress) bool {
|
||||||
if len(lhs) != len(rhs) {
|
if len(lhs) != len(rhs) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@ -308,7 +287,7 @@ func ingressSliceEqual(lhs, rhs []LoadBalancerIngress) bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func ingressEqual(lhs, rhs *LoadBalancerIngress) bool {
|
func ingressEqual(lhs, rhs *api.LoadBalancerIngress) bool {
|
||||||
if lhs.IP != rhs.IP {
|
if lhs.IP != rhs.IP {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@ -319,9 +298,9 @@ func ingressEqual(lhs, rhs *LoadBalancerIngress) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: make method on LoadBalancerStatus?
|
// TODO: make method on LoadBalancerStatus?
|
||||||
func LoadBalancerStatusDeepCopy(lb *LoadBalancerStatus) *LoadBalancerStatus {
|
func LoadBalancerStatusDeepCopy(lb *api.LoadBalancerStatus) *api.LoadBalancerStatus {
|
||||||
c := &LoadBalancerStatus{}
|
c := &api.LoadBalancerStatus{}
|
||||||
c.Ingress = make([]LoadBalancerIngress, len(lb.Ingress))
|
c.Ingress = make([]api.LoadBalancerIngress, len(lb.Ingress))
|
||||||
for i := range lb.Ingress {
|
for i := range lb.Ingress {
|
||||||
c.Ingress[i] = lb.Ingress[i]
|
c.Ingress[i] = lb.Ingress[i]
|
||||||
}
|
}
|
||||||
@ -330,42 +309,42 @@ func LoadBalancerStatusDeepCopy(lb *LoadBalancerStatus) *LoadBalancerStatus {
|
|||||||
|
|
||||||
// GetAccessModesAsString returns a string representation of an array of access modes.
|
// GetAccessModesAsString returns a string representation of an array of access modes.
|
||||||
// modes, when present, are always in the same order: RWO,ROX,RWX.
|
// modes, when present, are always in the same order: RWO,ROX,RWX.
|
||||||
func GetAccessModesAsString(modes []PersistentVolumeAccessMode) string {
|
func GetAccessModesAsString(modes []api.PersistentVolumeAccessMode) string {
|
||||||
modes = removeDuplicateAccessModes(modes)
|
modes = removeDuplicateAccessModes(modes)
|
||||||
modesStr := []string{}
|
modesStr := []string{}
|
||||||
if containsAccessMode(modes, ReadWriteOnce) {
|
if containsAccessMode(modes, api.ReadWriteOnce) {
|
||||||
modesStr = append(modesStr, "RWO")
|
modesStr = append(modesStr, "RWO")
|
||||||
}
|
}
|
||||||
if containsAccessMode(modes, ReadOnlyMany) {
|
if containsAccessMode(modes, api.ReadOnlyMany) {
|
||||||
modesStr = append(modesStr, "ROX")
|
modesStr = append(modesStr, "ROX")
|
||||||
}
|
}
|
||||||
if containsAccessMode(modes, ReadWriteMany) {
|
if containsAccessMode(modes, api.ReadWriteMany) {
|
||||||
modesStr = append(modesStr, "RWX")
|
modesStr = append(modesStr, "RWX")
|
||||||
}
|
}
|
||||||
return strings.Join(modesStr, ",")
|
return strings.Join(modesStr, ",")
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetAccessModesAsString returns an array of AccessModes from a string created by GetAccessModesAsString
|
// GetAccessModesAsString returns an array of AccessModes from a string created by GetAccessModesAsString
|
||||||
func GetAccessModesFromString(modes string) []PersistentVolumeAccessMode {
|
func GetAccessModesFromString(modes string) []api.PersistentVolumeAccessMode {
|
||||||
strmodes := strings.Split(modes, ",")
|
strmodes := strings.Split(modes, ",")
|
||||||
accessModes := []PersistentVolumeAccessMode{}
|
accessModes := []api.PersistentVolumeAccessMode{}
|
||||||
for _, s := range strmodes {
|
for _, s := range strmodes {
|
||||||
s = strings.Trim(s, " ")
|
s = strings.Trim(s, " ")
|
||||||
switch {
|
switch {
|
||||||
case s == "RWO":
|
case s == "RWO":
|
||||||
accessModes = append(accessModes, ReadWriteOnce)
|
accessModes = append(accessModes, api.ReadWriteOnce)
|
||||||
case s == "ROX":
|
case s == "ROX":
|
||||||
accessModes = append(accessModes, ReadOnlyMany)
|
accessModes = append(accessModes, api.ReadOnlyMany)
|
||||||
case s == "RWX":
|
case s == "RWX":
|
||||||
accessModes = append(accessModes, ReadWriteMany)
|
accessModes = append(accessModes, api.ReadWriteMany)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return accessModes
|
return accessModes
|
||||||
}
|
}
|
||||||
|
|
||||||
// removeDuplicateAccessModes returns an array of access modes without any duplicates
|
// removeDuplicateAccessModes returns an array of access modes without any duplicates
|
||||||
func removeDuplicateAccessModes(modes []PersistentVolumeAccessMode) []PersistentVolumeAccessMode {
|
func removeDuplicateAccessModes(modes []api.PersistentVolumeAccessMode) []api.PersistentVolumeAccessMode {
|
||||||
accessModes := []PersistentVolumeAccessMode{}
|
accessModes := []api.PersistentVolumeAccessMode{}
|
||||||
for _, m := range modes {
|
for _, m := range modes {
|
||||||
if !containsAccessMode(accessModes, m) {
|
if !containsAccessMode(accessModes, m) {
|
||||||
accessModes = append(accessModes, m)
|
accessModes = append(accessModes, m)
|
||||||
@ -374,7 +353,7 @@ func removeDuplicateAccessModes(modes []PersistentVolumeAccessMode) []Persistent
|
|||||||
return accessModes
|
return accessModes
|
||||||
}
|
}
|
||||||
|
|
||||||
func containsAccessMode(modes []PersistentVolumeAccessMode, mode PersistentVolumeAccessMode) bool {
|
func containsAccessMode(modes []api.PersistentVolumeAccessMode, mode api.PersistentVolumeAccessMode) bool {
|
||||||
for _, m := range modes {
|
for _, m := range modes {
|
||||||
if m == mode {
|
if m == mode {
|
||||||
return true
|
return true
|
||||||
@ -397,7 +376,7 @@ func ParseRFC3339(s string, nowFn func() metav1.Time) (metav1.Time, error) {
|
|||||||
|
|
||||||
// NodeSelectorRequirementsAsSelector converts the []NodeSelectorRequirement api type into a struct that implements
|
// NodeSelectorRequirementsAsSelector converts the []NodeSelectorRequirement api type into a struct that implements
|
||||||
// labels.Selector.
|
// labels.Selector.
|
||||||
func NodeSelectorRequirementsAsSelector(nsm []NodeSelectorRequirement) (labels.Selector, error) {
|
func NodeSelectorRequirementsAsSelector(nsm []api.NodeSelectorRequirement) (labels.Selector, error) {
|
||||||
if len(nsm) == 0 {
|
if len(nsm) == 0 {
|
||||||
return labels.Nothing(), nil
|
return labels.Nothing(), nil
|
||||||
}
|
}
|
||||||
@ -405,17 +384,17 @@ func NodeSelectorRequirementsAsSelector(nsm []NodeSelectorRequirement) (labels.S
|
|||||||
for _, expr := range nsm {
|
for _, expr := range nsm {
|
||||||
var op selection.Operator
|
var op selection.Operator
|
||||||
switch expr.Operator {
|
switch expr.Operator {
|
||||||
case NodeSelectorOpIn:
|
case api.NodeSelectorOpIn:
|
||||||
op = selection.In
|
op = selection.In
|
||||||
case NodeSelectorOpNotIn:
|
case api.NodeSelectorOpNotIn:
|
||||||
op = selection.NotIn
|
op = selection.NotIn
|
||||||
case NodeSelectorOpExists:
|
case api.NodeSelectorOpExists:
|
||||||
op = selection.Exists
|
op = selection.Exists
|
||||||
case NodeSelectorOpDoesNotExist:
|
case api.NodeSelectorOpDoesNotExist:
|
||||||
op = selection.DoesNotExist
|
op = selection.DoesNotExist
|
||||||
case NodeSelectorOpGt:
|
case api.NodeSelectorOpGt:
|
||||||
op = selection.GreaterThan
|
op = selection.GreaterThan
|
||||||
case NodeSelectorOpLt:
|
case api.NodeSelectorOpLt:
|
||||||
op = selection.LessThan
|
op = selection.LessThan
|
||||||
default:
|
default:
|
||||||
return nil, fmt.Errorf("%q is not a valid node selector operator", expr.Operator)
|
return nil, fmt.Errorf("%q is not a valid node selector operator", expr.Operator)
|
||||||
@ -431,10 +410,10 @@ func NodeSelectorRequirementsAsSelector(nsm []NodeSelectorRequirement) (labels.S
|
|||||||
|
|
||||||
// GetTolerationsFromPodAnnotations gets the json serialized tolerations data from Pod.Annotations
|
// GetTolerationsFromPodAnnotations gets the json serialized tolerations data from Pod.Annotations
|
||||||
// and converts it to the []Toleration type in api.
|
// and converts it to the []Toleration type in api.
|
||||||
func GetTolerationsFromPodAnnotations(annotations map[string]string) ([]Toleration, error) {
|
func GetTolerationsFromPodAnnotations(annotations map[string]string) ([]api.Toleration, error) {
|
||||||
var tolerations []Toleration
|
var tolerations []api.Toleration
|
||||||
if len(annotations) > 0 && annotations[TolerationsAnnotationKey] != "" {
|
if len(annotations) > 0 && annotations[api.TolerationsAnnotationKey] != "" {
|
||||||
err := json.Unmarshal([]byte(annotations[TolerationsAnnotationKey]), &tolerations)
|
err := json.Unmarshal([]byte(annotations[api.TolerationsAnnotationKey]), &tolerations)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return tolerations, err
|
return tolerations, err
|
||||||
}
|
}
|
||||||
@ -444,10 +423,10 @@ func GetTolerationsFromPodAnnotations(annotations map[string]string) ([]Tolerati
|
|||||||
|
|
||||||
// AddOrUpdateTolerationInPod tries to add a toleration to the pod's toleration list.
|
// AddOrUpdateTolerationInPod tries to add a toleration to the pod's toleration list.
|
||||||
// Returns true if something was updated, false otherwise.
|
// Returns true if something was updated, false otherwise.
|
||||||
func AddOrUpdateTolerationInPod(pod *Pod, toleration *Toleration) bool {
|
func AddOrUpdateTolerationInPod(pod *api.Pod, toleration *api.Toleration) bool {
|
||||||
podTolerations := pod.Spec.Tolerations
|
podTolerations := pod.Spec.Tolerations
|
||||||
|
|
||||||
var newTolerations []Toleration
|
var newTolerations []api.Toleration
|
||||||
updated := false
|
updated := false
|
||||||
for i := range podTolerations {
|
for i := range podTolerations {
|
||||||
if toleration.MatchToleration(&podTolerations[i]) {
|
if toleration.MatchToleration(&podTolerations[i]) {
|
||||||
@ -470,18 +449,8 @@ func AddOrUpdateTolerationInPod(pod *Pod, toleration *Toleration) bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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
|
|
||||||
}
|
|
||||||
|
|
||||||
// TolerationToleratesTaint checks if the toleration tolerates the taint.
|
// TolerationToleratesTaint checks if the toleration tolerates the taint.
|
||||||
func TolerationToleratesTaint(toleration *Toleration, taint *Taint) bool {
|
func TolerationToleratesTaint(toleration *api.Toleration, taint *api.Taint) bool {
|
||||||
if len(toleration.Effect) != 0 && toleration.Effect != taint.Effect {
|
if len(toleration.Effect) != 0 && toleration.Effect != taint.Effect {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@ -490,17 +459,17 @@ func TolerationToleratesTaint(toleration *Toleration, taint *Taint) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
// TODO: Use proper defaulting when Toleration becomes a field of PodSpec
|
// TODO: Use proper defaulting when Toleration becomes a field of PodSpec
|
||||||
if (len(toleration.Operator) == 0 || toleration.Operator == TolerationOpEqual) && toleration.Value == taint.Value {
|
if (len(toleration.Operator) == 0 || toleration.Operator == api.TolerationOpEqual) && toleration.Value == taint.Value {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if toleration.Operator == TolerationOpExists {
|
if toleration.Operator == api.TolerationOpExists {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// TaintToleratedByTolerations checks if taint is tolerated by any of the tolerations.
|
// TaintToleratedByTolerations checks if taint is tolerated by any of the tolerations.
|
||||||
func TaintToleratedByTolerations(taint *Taint, tolerations []Toleration) bool {
|
func TaintToleratedByTolerations(taint *api.Taint, tolerations []api.Toleration) bool {
|
||||||
tolerated := false
|
tolerated := false
|
||||||
for i := range tolerations {
|
for i := range tolerations {
|
||||||
if TolerationToleratesTaint(&tolerations[i], taint) {
|
if TolerationToleratesTaint(&tolerations[i], taint) {
|
||||||
@ -511,28 +480,14 @@ func TaintToleratedByTolerations(taint *Taint, tolerations []Toleration) bool {
|
|||||||
return tolerated
|
return tolerated
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetTaintsFromNodeAnnotations gets the json serialized taints data from Pod.Annotations
|
// GetTaintsFromNodeAnnotations gets the json serialized taints data from Pod.Annotations
|
||||||
// and converts it to the []Taint type in api.
|
// and converts it to the []Taint type in api.
|
||||||
func GetTaintsFromNodeAnnotations(annotations map[string]string) ([]Taint, error) {
|
func GetTaintsFromNodeAnnotations(annotations map[string]string) ([]api.Taint, error) {
|
||||||
var taints []Taint
|
var taints []api.Taint
|
||||||
if len(annotations) > 0 && annotations[TaintsAnnotationKey] != "" {
|
if len(annotations) > 0 && annotations[api.TaintsAnnotationKey] != "" {
|
||||||
err := json.Unmarshal([]byte(annotations[TaintsAnnotationKey]), &taints)
|
err := json.Unmarshal([]byte(annotations[api.TaintsAnnotationKey]), &taints)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return []Taint{}, err
|
return []api.Taint{}, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return taints, nil
|
return taints, nil
|
||||||
@ -541,12 +496,12 @@ func GetTaintsFromNodeAnnotations(annotations map[string]string) ([]Taint, error
|
|||||||
// SysctlsFromPodAnnotations parses the sysctl annotations into a slice of safe Sysctls
|
// SysctlsFromPodAnnotations parses the sysctl annotations into a slice of safe Sysctls
|
||||||
// and a slice of unsafe Sysctls. This is only a convenience wrapper around
|
// and a slice of unsafe Sysctls. This is only a convenience wrapper around
|
||||||
// SysctlsFromPodAnnotation.
|
// SysctlsFromPodAnnotation.
|
||||||
func SysctlsFromPodAnnotations(a map[string]string) ([]Sysctl, []Sysctl, error) {
|
func SysctlsFromPodAnnotations(a map[string]string) ([]api.Sysctl, []api.Sysctl, error) {
|
||||||
safe, err := SysctlsFromPodAnnotation(a[SysctlsPodAnnotationKey])
|
safe, err := SysctlsFromPodAnnotation(a[api.SysctlsPodAnnotationKey])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
unsafe, err := SysctlsFromPodAnnotation(a[UnsafeSysctlsPodAnnotationKey])
|
unsafe, err := SysctlsFromPodAnnotation(a[api.UnsafeSysctlsPodAnnotationKey])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
@ -555,13 +510,13 @@ func SysctlsFromPodAnnotations(a map[string]string) ([]Sysctl, []Sysctl, error)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SysctlsFromPodAnnotation parses an annotation value into a slice of Sysctls.
|
// SysctlsFromPodAnnotation parses an annotation value into a slice of Sysctls.
|
||||||
func SysctlsFromPodAnnotation(annotation string) ([]Sysctl, error) {
|
func SysctlsFromPodAnnotation(annotation string) ([]api.Sysctl, error) {
|
||||||
if len(annotation) == 0 {
|
if len(annotation) == 0 {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
kvs := strings.Split(annotation, ",")
|
kvs := strings.Split(annotation, ",")
|
||||||
sysctls := make([]Sysctl, len(kvs))
|
sysctls := make([]api.Sysctl, len(kvs))
|
||||||
for i, kv := range kvs {
|
for i, kv := range kvs {
|
||||||
cs := strings.Split(kv, "=")
|
cs := strings.Split(kv, "=")
|
||||||
if len(cs) != 2 || len(cs[0]) == 0 {
|
if len(cs) != 2 || len(cs[0]) == 0 {
|
||||||
@ -574,7 +529,7 @@ func SysctlsFromPodAnnotation(annotation string) ([]Sysctl, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// PodAnnotationsFromSysctls creates an annotation value for a slice of Sysctls.
|
// PodAnnotationsFromSysctls creates an annotation value for a slice of Sysctls.
|
||||||
func PodAnnotationsFromSysctls(sysctls []Sysctl) string {
|
func PodAnnotationsFromSysctls(sysctls []api.Sysctl) string {
|
||||||
if len(sysctls) == 0 {
|
if len(sysctls) == 0 {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
@ -589,10 +544,10 @@ func PodAnnotationsFromSysctls(sysctls []Sysctl) string {
|
|||||||
// GetAffinityFromPodAnnotations gets the json serialized affinity data from Pod.Annotations
|
// GetAffinityFromPodAnnotations gets the json serialized affinity data from Pod.Annotations
|
||||||
// and converts it to the Affinity type in api.
|
// and converts it to the Affinity type in api.
|
||||||
// TODO: remove when alpha support for affinity is removed
|
// TODO: remove when alpha support for affinity is removed
|
||||||
func GetAffinityFromPodAnnotations(annotations map[string]string) (*Affinity, error) {
|
func GetAffinityFromPodAnnotations(annotations map[string]string) (*api.Affinity, error) {
|
||||||
if len(annotations) > 0 && annotations[AffinityAnnotationKey] != "" {
|
if len(annotations) > 0 && annotations[api.AffinityAnnotationKey] != "" {
|
||||||
var affinity Affinity
|
var affinity api.Affinity
|
||||||
err := json.Unmarshal([]byte(annotations[AffinityAnnotationKey]), &affinity)
|
err := json.Unmarshal([]byte(annotations[api.AffinityAnnotationKey]), &affinity)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -602,9 +557,9 @@ func GetAffinityFromPodAnnotations(annotations map[string]string) (*Affinity, er
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetPersistentVolumeClass returns StorageClassName.
|
// GetPersistentVolumeClass returns StorageClassName.
|
||||||
func GetPersistentVolumeClass(volume *PersistentVolume) string {
|
func GetPersistentVolumeClass(volume *api.PersistentVolume) string {
|
||||||
// Use beta annotation first
|
// Use beta annotation first
|
||||||
if class, found := volume.Annotations[BetaStorageClassAnnotation]; found {
|
if class, found := volume.Annotations[api.BetaStorageClassAnnotation]; found {
|
||||||
return class
|
return class
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -613,9 +568,9 @@ func GetPersistentVolumeClass(volume *PersistentVolume) string {
|
|||||||
|
|
||||||
// GetPersistentVolumeClaimClass returns StorageClassName. If no storage class was
|
// GetPersistentVolumeClaimClass returns StorageClassName. If no storage class was
|
||||||
// requested, it returns "".
|
// requested, it returns "".
|
||||||
func GetPersistentVolumeClaimClass(claim *PersistentVolumeClaim) string {
|
func GetPersistentVolumeClaimClass(claim *api.PersistentVolumeClaim) string {
|
||||||
// Use beta annotation first
|
// Use beta annotation first
|
||||||
if class, found := claim.Annotations[BetaStorageClassAnnotation]; found {
|
if class, found := claim.Annotations[api.BetaStorageClassAnnotation]; found {
|
||||||
return class
|
return class
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -627,9 +582,9 @@ func GetPersistentVolumeClaimClass(claim *PersistentVolumeClaim) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// PersistentVolumeClaimHasClass returns true if given claim has set StorageClassName field.
|
// PersistentVolumeClaimHasClass returns true if given claim has set StorageClassName field.
|
||||||
func PersistentVolumeClaimHasClass(claim *PersistentVolumeClaim) bool {
|
func PersistentVolumeClaimHasClass(claim *api.PersistentVolumeClaim) bool {
|
||||||
// Use beta annotation first
|
// Use beta annotation first
|
||||||
if _, found := claim.Annotations[BetaStorageClassAnnotation]; found {
|
if _, found := claim.Annotations[api.BetaStorageClassAnnotation]; found {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
46
staging/src/k8s.io/client-go/pkg/api/methods.go
Normal file
46
staging/src/k8s.io/client-go/pkg/api/methods.go
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
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"
|
||||||
|
|
||||||
|
// 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
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
}
|
@ -28,6 +28,7 @@ import (
|
|||||||
"k8s.io/apimachinery/pkg/util/sets"
|
"k8s.io/apimachinery/pkg/util/sets"
|
||||||
|
|
||||||
"k8s.io/client-go/pkg/api"
|
"k8s.io/client-go/pkg/api"
|
||||||
|
"k8s.io/client-go/pkg/api/helper"
|
||||||
)
|
)
|
||||||
|
|
||||||
// IsOpaqueIntResourceName returns true if the resource name has the opaque
|
// IsOpaqueIntResourceName returns true if the resource name has the opaque
|
||||||
@ -285,7 +286,7 @@ func AddOrUpdateTolerationInPod(pod *Pod, toleration *Toleration) bool {
|
|||||||
updated := false
|
updated := false
|
||||||
for i := range podTolerations {
|
for i := range podTolerations {
|
||||||
if toleration.MatchToleration(&podTolerations[i]) {
|
if toleration.MatchToleration(&podTolerations[i]) {
|
||||||
if api.Semantic.DeepEqual(toleration, podTolerations[i]) {
|
if helper.Semantic.DeepEqual(toleration, podTolerations[i]) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
newTolerations = append(newTolerations, *toleration)
|
newTolerations = append(newTolerations, *toleration)
|
||||||
@ -527,7 +528,7 @@ func AddOrUpdateTaint(node *Node, taint *Taint) (*Node, bool, error) {
|
|||||||
updated := false
|
updated := false
|
||||||
for i := range nodeTaints {
|
for i := range nodeTaints {
|
||||||
if taint.MatchTaint(&nodeTaints[i]) {
|
if taint.MatchTaint(&nodeTaints[i]) {
|
||||||
if api.Semantic.DeepEqual(taint, nodeTaints[i]) {
|
if helper.Semantic.DeepEqual(taint, nodeTaints[i]) {
|
||||||
return newNode, false, nil
|
return newNode, false, nil
|
||||||
}
|
}
|
||||||
newTaints = append(newTaints, *taint)
|
newTaints = append(newTaints, *taint)
|
||||||
|
@ -65,7 +65,6 @@ func RegisterDeepCopies(scheme *runtime.Scheme) error {
|
|||||||
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_api_ContainerStateTerminated, InType: reflect.TypeOf(&ContainerStateTerminated{})},
|
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_api_ContainerStateTerminated, InType: reflect.TypeOf(&ContainerStateTerminated{})},
|
||||||
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_api_ContainerStateWaiting, InType: reflect.TypeOf(&ContainerStateWaiting{})},
|
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_api_ContainerStateWaiting, InType: reflect.TypeOf(&ContainerStateWaiting{})},
|
||||||
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_api_ContainerStatus, InType: reflect.TypeOf(&ContainerStatus{})},
|
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_api_ContainerStatus, InType: reflect.TypeOf(&ContainerStatus{})},
|
||||||
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_api_ConversionError, InType: reflect.TypeOf(&ConversionError{})},
|
|
||||||
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_api_DaemonEndpoint, InType: reflect.TypeOf(&DaemonEndpoint{})},
|
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_api_DaemonEndpoint, InType: reflect.TypeOf(&DaemonEndpoint{})},
|
||||||
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_api_DeleteOptions, InType: reflect.TypeOf(&DeleteOptions{})},
|
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_api_DeleteOptions, InType: reflect.TypeOf(&DeleteOptions{})},
|
||||||
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_api_DownwardAPIProjection, InType: reflect.TypeOf(&DownwardAPIProjection{})},
|
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_api_DownwardAPIProjection, InType: reflect.TypeOf(&DownwardAPIProjection{})},
|
||||||
@ -707,31 +706,6 @@ func DeepCopy_api_ContainerStatus(in interface{}, out interface{}, c *conversion
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func DeepCopy_api_ConversionError(in interface{}, out interface{}, c *conversion.Cloner) error {
|
|
||||||
{
|
|
||||||
in := in.(*ConversionError)
|
|
||||||
out := out.(*ConversionError)
|
|
||||||
*out = *in
|
|
||||||
// in.In is kind 'Interface'
|
|
||||||
if in.In != nil {
|
|
||||||
if newVal, err := c.DeepCopy(&in.In); err != nil {
|
|
||||||
return err
|
|
||||||
} else {
|
|
||||||
out.In = *newVal.(*interface{})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// in.Out is kind 'Interface'
|
|
||||||
if in.Out != nil {
|
|
||||||
if newVal, err := c.DeepCopy(&in.Out); err != nil {
|
|
||||||
return err
|
|
||||||
} else {
|
|
||||||
out.Out = *newVal.(*interface{})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func DeepCopy_api_DaemonEndpoint(in interface{}, out interface{}, c *conversion.Cloner) error {
|
func DeepCopy_api_DaemonEndpoint(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||||
{
|
{
|
||||||
in := in.(*DaemonEndpoint)
|
in := in.(*DaemonEndpoint)
|
||||||
|
@ -24,6 +24,7 @@ import (
|
|||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
restclient "k8s.io/client-go/rest"
|
restclient "k8s.io/client-go/rest"
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
|
"k8s.io/kubernetes/pkg/api/helper"
|
||||||
"k8s.io/kubernetes/pkg/api/v1"
|
"k8s.io/kubernetes/pkg/api/v1"
|
||||||
"k8s.io/kubernetes/pkg/client/clientset_generated/clientset"
|
"k8s.io/kubernetes/pkg/client/clientset_generated/clientset"
|
||||||
"k8s.io/kubernetes/plugin/pkg/admission/defaulttolerationseconds"
|
"k8s.io/kubernetes/plugin/pkg/admission/defaulttolerationseconds"
|
||||||
@ -85,13 +86,13 @@ func TestAdmission(t *testing.T) {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
if tolerations[i].MatchToleration(&nodeNotReady) {
|
if tolerations[i].MatchToleration(&nodeNotReady) {
|
||||||
if api.Semantic.DeepEqual(tolerations[i], nodeNotReady) {
|
if helper.Semantic.DeepEqual(tolerations[i], nodeNotReady) {
|
||||||
found++
|
found++
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if tolerations[i].MatchToleration(&nodeUnreachable) {
|
if tolerations[i].MatchToleration(&nodeUnreachable) {
|
||||||
if api.Semantic.DeepEqual(tolerations[i], nodeUnreachable) {
|
if helper.Semantic.DeepEqual(tolerations[i], nodeUnreachable) {
|
||||||
found++
|
found++
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
23
vendor/BUILD
vendored
23
vendor/BUILD
vendored
@ -13903,8 +13903,8 @@ go_library(
|
|||||||
"k8s.io/client-go/pkg/api/defaults.go",
|
"k8s.io/client-go/pkg/api/defaults.go",
|
||||||
"k8s.io/client-go/pkg/api/doc.go",
|
"k8s.io/client-go/pkg/api/doc.go",
|
||||||
"k8s.io/client-go/pkg/api/field_constants.go",
|
"k8s.io/client-go/pkg/api/field_constants.go",
|
||||||
"k8s.io/client-go/pkg/api/helpers.go",
|
|
||||||
"k8s.io/client-go/pkg/api/json.go",
|
"k8s.io/client-go/pkg/api/json.go",
|
||||||
|
"k8s.io/client-go/pkg/api/methods.go",
|
||||||
"k8s.io/client-go/pkg/api/ref.go",
|
"k8s.io/client-go/pkg/api/ref.go",
|
||||||
"k8s.io/client-go/pkg/api/register.go",
|
"k8s.io/client-go/pkg/api/register.go",
|
||||||
"k8s.io/client-go/pkg/api/resource_helpers.go",
|
"k8s.io/client-go/pkg/api/resource_helpers.go",
|
||||||
@ -13913,7 +13913,6 @@ go_library(
|
|||||||
],
|
],
|
||||||
tags = ["automanaged"],
|
tags = ["automanaged"],
|
||||||
deps = [
|
deps = [
|
||||||
"//vendor:github.com/davecgh/go-spew/spew",
|
|
||||||
"//vendor:k8s.io/apimachinery/pkg/api/meta",
|
"//vendor:k8s.io/apimachinery/pkg/api/meta",
|
||||||
"//vendor:k8s.io/apimachinery/pkg/api/resource",
|
"//vendor:k8s.io/apimachinery/pkg/api/resource",
|
||||||
"//vendor:k8s.io/apimachinery/pkg/apimachinery/announced",
|
"//vendor:k8s.io/apimachinery/pkg/apimachinery/announced",
|
||||||
@ -13925,10 +13924,8 @@ go_library(
|
|||||||
"//vendor:k8s.io/apimachinery/pkg/runtime",
|
"//vendor:k8s.io/apimachinery/pkg/runtime",
|
||||||
"//vendor:k8s.io/apimachinery/pkg/runtime/schema",
|
"//vendor:k8s.io/apimachinery/pkg/runtime/schema",
|
||||||
"//vendor:k8s.io/apimachinery/pkg/runtime/serializer",
|
"//vendor:k8s.io/apimachinery/pkg/runtime/serializer",
|
||||||
"//vendor:k8s.io/apimachinery/pkg/selection",
|
|
||||||
"//vendor:k8s.io/apimachinery/pkg/types",
|
"//vendor:k8s.io/apimachinery/pkg/types",
|
||||||
"//vendor:k8s.io/apimachinery/pkg/util/intstr",
|
"//vendor:k8s.io/apimachinery/pkg/util/intstr",
|
||||||
"//vendor:k8s.io/apimachinery/pkg/util/sets",
|
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -13985,6 +13982,7 @@ go_library(
|
|||||||
"//vendor:k8s.io/apimachinery/pkg/util/sets",
|
"//vendor:k8s.io/apimachinery/pkg/util/sets",
|
||||||
"//vendor:k8s.io/apimachinery/pkg/util/validation/field",
|
"//vendor:k8s.io/apimachinery/pkg/util/validation/field",
|
||||||
"//vendor:k8s.io/client-go/pkg/api",
|
"//vendor:k8s.io/client-go/pkg/api",
|
||||||
|
"//vendor:k8s.io/client-go/pkg/api/helper",
|
||||||
"//vendor:k8s.io/client-go/pkg/apis/extensions",
|
"//vendor:k8s.io/client-go/pkg/apis/extensions",
|
||||||
"//vendor:k8s.io/client-go/pkg/util",
|
"//vendor:k8s.io/client-go/pkg/util",
|
||||||
"//vendor:k8s.io/client-go/pkg/util/parsers",
|
"//vendor:k8s.io/client-go/pkg/util/parsers",
|
||||||
@ -16761,3 +16759,20 @@ filegroup(
|
|||||||
srcs = [":package-srcs"],
|
srcs = [":package-srcs"],
|
||||||
tags = ["automanaged"],
|
tags = ["automanaged"],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
go_library(
|
||||||
|
name = "k8s.io/client-go/pkg/api/helper",
|
||||||
|
srcs = ["k8s.io/client-go/pkg/api/helper/helpers.go"],
|
||||||
|
tags = ["automanaged"],
|
||||||
|
deps = [
|
||||||
|
"//vendor:k8s.io/apimachinery/pkg/api/resource",
|
||||||
|
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
|
||||||
|
"//vendor:k8s.io/apimachinery/pkg/conversion",
|
||||||
|
"//vendor:k8s.io/apimachinery/pkg/fields",
|
||||||
|
"//vendor:k8s.io/apimachinery/pkg/labels",
|
||||||
|
"//vendor:k8s.io/apimachinery/pkg/runtime",
|
||||||
|
"//vendor:k8s.io/apimachinery/pkg/selection",
|
||||||
|
"//vendor:k8s.io/apimachinery/pkg/util/sets",
|
||||||
|
"//vendor:k8s.io/client-go/pkg/api",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user