diff --git a/federation/pkg/kubefed/init/BUILD b/federation/pkg/kubefed/init/BUILD index 0acaf02d7235..a20536612cee 100644 --- a/federation/pkg/kubefed/init/BUILD +++ b/federation/pkg/kubefed/init/BUILD @@ -47,6 +47,7 @@ go_test( "//federation/pkg/kubefed/testing:go_default_library", "//federation/pkg/kubefed/util:go_default_library", "//pkg/api:go_default_library", + "//pkg/api/helper:go_default_library", "//pkg/api/testapi:go_default_library", "//pkg/api/v1:go_default_library", "//pkg/apis/extensions/v1beta1:go_default_library", diff --git a/federation/pkg/kubefed/init/init_test.go b/federation/pkg/kubefed/init/init_test.go index 9ce6f8b76b58..64894360d7b1 100644 --- a/federation/pkg/kubefed/init/init_test.go +++ b/federation/pkg/kubefed/init/init_test.go @@ -46,6 +46,7 @@ import ( kubefedtesting "k8s.io/kubernetes/federation/pkg/kubefed/testing" "k8s.io/kubernetes/federation/pkg/kubefed/util" "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/helper" "k8s.io/kubernetes/pkg/api/testapi" "k8s.io/kubernetes/pkg/api/v1" "k8s.io/kubernetes/pkg/apis/extensions/v1beta1" @@ -1243,7 +1244,7 @@ func fakeInitHostFactory(apiserverServiceType v1.ServiceType, federationName, na if err != nil { 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 &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 { 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 &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 { 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 &http.Response{StatusCode: http.StatusCreated, Header: kubefedtesting.DefaultHeader(), Body: kubefedtesting.ObjBody(rbacCodec, &rolebinding)}, nil diff --git a/pkg/api/BUILD b/pkg/api/BUILD index 862d13476a48..71bf4f8e11f0 100644 --- a/pkg/api/BUILD +++ b/pkg/api/BUILD @@ -15,8 +15,8 @@ go_library( "defaults.go", "doc.go", "field_constants.go", - "helpers.go", "json.go", + "methods.go", "ref.go", "register.go", "resource_helpers.go", @@ -25,7 +25,6 @@ go_library( ], tags = ["automanaged"], deps = [ - "//vendor:github.com/davecgh/go-spew/spew", "//vendor:k8s.io/apimachinery/pkg/api/meta", "//vendor:k8s.io/apimachinery/pkg/api/resource", "//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/schema", "//vendor:k8s.io/apimachinery/pkg/runtime/serializer", - "//vendor:k8s.io/apimachinery/pkg/selection", "//vendor:k8s.io/apimachinery/pkg/types", "//vendor:k8s.io/apimachinery/pkg/util/intstr", - "//vendor:k8s.io/apimachinery/pkg/util/sets", ], ) go_test( name = "go_default_test", srcs = [ - "helpers_test.go", + "methods_test.go", "ref_test.go", "resource_helpers_test.go", ], @@ -56,7 +53,6 @@ go_test( deps = [ "//vendor:k8s.io/apimachinery/pkg/api/resource", "//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/schema", ], @@ -120,6 +116,7 @@ filegroup( "//pkg/api/endpoints:all-srcs", "//pkg/api/errors:all-srcs", "//pkg/api/events:all-srcs", + "//pkg/api/helper:all-srcs", "//pkg/api/install:all-srcs", "//pkg/api/meta:all-srcs", "//pkg/api/pod:all-srcs", diff --git a/pkg/api/annotation_key_constants.go b/pkg/api/annotation_key_constants.go index 07732451f901..30331f982d30 100644 --- a/pkg/api/annotation_key_constants.go +++ b/pkg/api/annotation_key_constants.go @@ -64,4 +64,7 @@ const ( // in the Annotations of a Pod. // TODO: remove when alpha support for affinity is removed AffinityAnnotationKey string = "scheduler.alpha.kubernetes.io/affinity" + + // annotation key prefix used to identify non-convertible json paths. + NonConvertibleAnnotationPrefix = "non-convertible.kubernetes.io" ) diff --git a/pkg/api/helper/BUILD b/pkg/api/helper/BUILD new file mode 100644 index 000000000000..7dd1bc43488c --- /dev/null +++ b/pkg/api/helper/BUILD @@ -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"], +) diff --git a/pkg/api/helpers.go b/pkg/api/helper/helpers.go similarity index 60% rename from pkg/api/helpers.go rename to pkg/api/helper/helpers.go index f7e7afbdbc40..ddf44ea783f5 100644 --- a/pkg/api/helpers.go +++ b/pkg/api/helper/helpers.go @@ -14,18 +14,15 @@ See the License for the specific language governing permissions and limitations under the License. */ -package api +package helper import ( "crypto/md5" "encoding/json" "fmt" - "reflect" "strings" "time" - "github.com/davecgh/go-spew/spew" - "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/conversion" @@ -34,25 +31,7 @@ import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/selection" "k8s.io/apimachinery/pkg/util/sets" -) - -// 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" + "k8s.io/kubernetes/pkg/api" ) // 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 { nonConvertibleKeys := map[string]string{} for key, value := range annotations { - if strings.HasPrefix(key, NonConvertibleAnnotationPrefix) { + if strings.HasPrefix(key, api.NonConvertibleAnnotationPrefix) { nonConvertibleKeys[key] = value } } @@ -89,10 +68,10 @@ var Semantic = conversion.EqualitiesOrDie( ) var standardResourceQuotaScopes = sets.NewString( - string(ResourceQuotaScopeTerminating), - string(ResourceQuotaScopeNotTerminating), - string(ResourceQuotaScopeBestEffort), - string(ResourceQuotaScopeNotBestEffort), + string(api.ResourceQuotaScopeTerminating), + string(api.ResourceQuotaScopeNotTerminating), + string(api.ResourceQuotaScopeBestEffort), + string(api.ResourceQuotaScopeNotBestEffort), ) // IsStandardResourceQuotaScope returns true if the scope is a standard value @@ -101,24 +80,24 @@ func IsStandardResourceQuotaScope(str string) bool { } var podObjectCountQuotaResources = sets.NewString( - string(ResourcePods), + string(api.ResourcePods), ) var podComputeQuotaResources = sets.NewString( - string(ResourceCPU), - string(ResourceMemory), - string(ResourceLimitsCPU), - string(ResourceLimitsMemory), - string(ResourceRequestsCPU), - string(ResourceRequestsMemory), + string(api.ResourceCPU), + string(api.ResourceMemory), + string(api.ResourceLimitsCPU), + string(api.ResourceLimitsMemory), + string(api.ResourceRequestsCPU), + string(api.ResourceRequestsMemory), ) // IsResourceQuotaScopeValidForResource returns true if the resource applies to the specified scope -func IsResourceQuotaScopeValidForResource(scope ResourceQuotaScope, resource string) bool { +func IsResourceQuotaScopeValidForResource(scope api.ResourceQuotaScope, resource string) bool { switch scope { - case ResourceQuotaScopeTerminating, ResourceQuotaScopeNotTerminating, ResourceQuotaScopeNotBestEffort: + case api.ResourceQuotaScopeTerminating, api.ResourceQuotaScopeNotTerminating, api.ResourceQuotaScopeNotBestEffort: return podObjectCountQuotaResources.Has(resource) || podComputeQuotaResources.Has(resource) - case ResourceQuotaScopeBestEffort: + case api.ResourceQuotaScopeBestEffort: return podObjectCountQuotaResources.Has(resource) default: return true @@ -126,8 +105,8 @@ func IsResourceQuotaScopeValidForResource(scope ResourceQuotaScope, resource str } var standardContainerResources = sets.NewString( - string(ResourceCPU), - string(ResourceMemory), + string(api.ResourceCPU), + string(api.ResourceMemory), ) // 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 // integer resource prefix. -func IsOpaqueIntResourceName(name ResourceName) bool { - return strings.HasPrefix(string(name), ResourceOpaqueIntPrefix) +func IsOpaqueIntResourceName(name api.ResourceName) bool { + return strings.HasPrefix(string(name), api.ResourceOpaqueIntPrefix) } // OpaqueIntResourceName returns a ResourceName with the canonical opaque // integer prefix prepended. If the argument already has the prefix, it is // returned unmodified. -func OpaqueIntResourceName(name string) ResourceName { - if IsOpaqueIntResourceName(ResourceName(name)) { - return ResourceName(name) +func OpaqueIntResourceName(name string) api.ResourceName { + if IsOpaqueIntResourceName(api.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( - string(LimitTypePod), - string(LimitTypeContainer), - string(LimitTypePersistentVolumeClaim), + string(api.LimitTypePod), + string(api.LimitTypeContainer), + string(api.LimitTypePersistentVolumeClaim), ) // IsStandardLimitRangeType returns true if the type is Pod or Container @@ -164,22 +143,22 @@ func IsStandardLimitRangeType(str string) bool { } var standardQuotaResources = sets.NewString( - string(ResourceCPU), - string(ResourceMemory), - string(ResourceRequestsCPU), - string(ResourceRequestsMemory), - string(ResourceRequestsStorage), - string(ResourceLimitsCPU), - string(ResourceLimitsMemory), - string(ResourcePods), - string(ResourceQuotas), - string(ResourceServices), - string(ResourceReplicationControllers), - string(ResourceSecrets), - string(ResourcePersistentVolumeClaims), - string(ResourceConfigMaps), - string(ResourceServicesNodePorts), - string(ResourceServicesLoadBalancers), + string(api.ResourceCPU), + string(api.ResourceMemory), + string(api.ResourceRequestsCPU), + string(api.ResourceRequestsMemory), + string(api.ResourceRequestsStorage), + string(api.ResourceLimitsCPU), + string(api.ResourceLimitsMemory), + string(api.ResourcePods), + string(api.ResourceQuotas), + string(api.ResourceServices), + string(api.ResourceReplicationControllers), + string(api.ResourceSecrets), + string(api.ResourcePersistentVolumeClaims), + string(api.ResourceConfigMaps), + string(api.ResourceServicesNodePorts), + string(api.ResourceServicesLoadBalancers), ) // IsStandardQuotaResourceName returns true if the resource is known to @@ -189,21 +168,21 @@ func IsStandardQuotaResourceName(str string) bool { } var standardResources = sets.NewString( - string(ResourceCPU), - string(ResourceMemory), - string(ResourceRequestsCPU), - string(ResourceRequestsMemory), - string(ResourceLimitsCPU), - string(ResourceLimitsMemory), - string(ResourcePods), - string(ResourceQuotas), - string(ResourceServices), - string(ResourceReplicationControllers), - string(ResourceSecrets), - string(ResourceConfigMaps), - string(ResourcePersistentVolumeClaims), - string(ResourceStorage), - string(ResourceRequestsStorage), + string(api.ResourceCPU), + string(api.ResourceMemory), + string(api.ResourceRequestsCPU), + string(api.ResourceRequestsMemory), + string(api.ResourceLimitsCPU), + string(api.ResourceLimitsMemory), + string(api.ResourcePods), + string(api.ResourceQuotas), + string(api.ResourceServices), + string(api.ResourceReplicationControllers), + string(api.ResourceSecrets), + string(api.ResourceConfigMaps), + string(api.ResourcePersistentVolumeClaims), + string(api.ResourceStorage), + string(api.ResourceRequestsStorage), ) // IsStandardResourceName returns true if the resource is known to the system @@ -212,50 +191,50 @@ func IsStandardResourceName(str string) bool { } var integerResources = sets.NewString( - string(ResourcePods), - string(ResourceQuotas), - string(ResourceServices), - string(ResourceReplicationControllers), - string(ResourceSecrets), - string(ResourceConfigMaps), - string(ResourcePersistentVolumeClaims), - string(ResourceServicesNodePorts), - string(ResourceServicesLoadBalancers), + string(api.ResourcePods), + string(api.ResourceQuotas), + string(api.ResourceServices), + string(api.ResourceReplicationControllers), + string(api.ResourceSecrets), + string(api.ResourceConfigMaps), + string(api.ResourcePersistentVolumeClaims), + string(api.ResourceServicesNodePorts), + string(api.ResourceServicesLoadBalancers), ) // IsIntegerResourceName returns true if the resource is measured in integer values func IsIntegerResourceName(str string) bool { - return integerResources.Has(str) || 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 // the objective is not to perform validation here -func IsServiceIPSet(service *Service) bool { - return service.Spec.ClusterIP != ClusterIPNone && service.Spec.ClusterIP != "" +func IsServiceIPSet(service *api.Service) bool { + return service.Spec.ClusterIP != api.ClusterIPNone && service.Spec.ClusterIP != "" } // this function aims to check if the service's cluster IP is requested or not -func IsServiceIPRequested(service *Service) bool { +func IsServiceIPRequested(service *api.Service) bool { // 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 service.Spec.ClusterIP == "" } var standardFinalizers = sets.NewString( - string(FinalizerKubernetes), + string(api.FinalizerKubernetes), metav1.FinalizerOrphanDependents, ) // 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] return found } // 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 { 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, // 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 { exists := false for _, existing := range *addresses { @@ -292,11 +271,11 @@ func HashObject(obj runtime.Object, codec runtime.Codec) (string, error) { } // TODO: make method on LoadBalancerStatus? -func LoadBalancerStatusEqual(l, r *LoadBalancerStatus) bool { +func LoadBalancerStatusEqual(l, r *api.LoadBalancerStatus) bool { return ingressSliceEqual(l.Ingress, r.Ingress) } -func ingressSliceEqual(lhs, rhs []LoadBalancerIngress) bool { +func ingressSliceEqual(lhs, rhs []api.LoadBalancerIngress) bool { if len(lhs) != len(rhs) { return false } @@ -308,7 +287,7 @@ func ingressSliceEqual(lhs, rhs []LoadBalancerIngress) bool { return true } -func ingressEqual(lhs, rhs *LoadBalancerIngress) bool { +func ingressEqual(lhs, rhs *api.LoadBalancerIngress) bool { if lhs.IP != rhs.IP { return false } @@ -319,9 +298,9 @@ func ingressEqual(lhs, rhs *LoadBalancerIngress) bool { } // TODO: make method on LoadBalancerStatus? -func LoadBalancerStatusDeepCopy(lb *LoadBalancerStatus) *LoadBalancerStatus { - c := &LoadBalancerStatus{} - c.Ingress = make([]LoadBalancerIngress, len(lb.Ingress)) +func LoadBalancerStatusDeepCopy(lb *api.LoadBalancerStatus) *api.LoadBalancerStatus { + c := &api.LoadBalancerStatus{} + c.Ingress = make([]api.LoadBalancerIngress, len(lb.Ingress)) for i := range lb.Ingress { c.Ingress[i] = lb.Ingress[i] } @@ -330,42 +309,42 @@ func LoadBalancerStatusDeepCopy(lb *LoadBalancerStatus) *LoadBalancerStatus { // GetAccessModesAsString returns a string representation of an array of access modes. // modes, when present, are always in the same order: RWO,ROX,RWX. -func GetAccessModesAsString(modes []PersistentVolumeAccessMode) string { +func GetAccessModesAsString(modes []api.PersistentVolumeAccessMode) string { modes = removeDuplicateAccessModes(modes) modesStr := []string{} - if containsAccessMode(modes, ReadWriteOnce) { + if containsAccessMode(modes, api.ReadWriteOnce) { modesStr = append(modesStr, "RWO") } - if containsAccessMode(modes, ReadOnlyMany) { + if containsAccessMode(modes, api.ReadOnlyMany) { modesStr = append(modesStr, "ROX") } - if containsAccessMode(modes, ReadWriteMany) { + if containsAccessMode(modes, api.ReadWriteMany) { modesStr = append(modesStr, "RWX") } return strings.Join(modesStr, ",") } // GetAccessModesAsString returns an array of AccessModes from a string created by GetAccessModesAsString -func GetAccessModesFromString(modes string) []PersistentVolumeAccessMode { +func GetAccessModesFromString(modes string) []api.PersistentVolumeAccessMode { strmodes := strings.Split(modes, ",") - accessModes := []PersistentVolumeAccessMode{} + accessModes := []api.PersistentVolumeAccessMode{} for _, s := range strmodes { s = strings.Trim(s, " ") switch { case s == "RWO": - accessModes = append(accessModes, ReadWriteOnce) + accessModes = append(accessModes, api.ReadWriteOnce) case s == "ROX": - accessModes = append(accessModes, ReadOnlyMany) + accessModes = append(accessModes, api.ReadOnlyMany) case s == "RWX": - accessModes = append(accessModes, ReadWriteMany) + accessModes = append(accessModes, api.ReadWriteMany) } } return accessModes } // removeDuplicateAccessModes returns an array of access modes without any duplicates -func removeDuplicateAccessModes(modes []PersistentVolumeAccessMode) []PersistentVolumeAccessMode { - accessModes := []PersistentVolumeAccessMode{} +func removeDuplicateAccessModes(modes []api.PersistentVolumeAccessMode) []api.PersistentVolumeAccessMode { + accessModes := []api.PersistentVolumeAccessMode{} for _, m := range modes { if !containsAccessMode(accessModes, m) { accessModes = append(accessModes, m) @@ -374,7 +353,7 @@ func removeDuplicateAccessModes(modes []PersistentVolumeAccessMode) []Persistent return accessModes } -func containsAccessMode(modes []PersistentVolumeAccessMode, mode PersistentVolumeAccessMode) bool { +func containsAccessMode(modes []api.PersistentVolumeAccessMode, mode api.PersistentVolumeAccessMode) bool { for _, m := range modes { if m == mode { 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 // labels.Selector. -func NodeSelectorRequirementsAsSelector(nsm []NodeSelectorRequirement) (labels.Selector, error) { +func NodeSelectorRequirementsAsSelector(nsm []api.NodeSelectorRequirement) (labels.Selector, error) { if len(nsm) == 0 { return labels.Nothing(), nil } @@ -405,17 +384,17 @@ func NodeSelectorRequirementsAsSelector(nsm []NodeSelectorRequirement) (labels.S for _, expr := range nsm { var op selection.Operator switch expr.Operator { - case NodeSelectorOpIn: + case api.NodeSelectorOpIn: op = selection.In - case NodeSelectorOpNotIn: + case api.NodeSelectorOpNotIn: op = selection.NotIn - case NodeSelectorOpExists: + case api.NodeSelectorOpExists: op = selection.Exists - case NodeSelectorOpDoesNotExist: + case api.NodeSelectorOpDoesNotExist: op = selection.DoesNotExist - case NodeSelectorOpGt: + case api.NodeSelectorOpGt: op = selection.GreaterThan - case NodeSelectorOpLt: + case api.NodeSelectorOpLt: op = selection.LessThan default: 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 // and converts it to the []Toleration type in api. -func GetTolerationsFromPodAnnotations(annotations map[string]string) ([]Toleration, error) { - var tolerations []Toleration - if len(annotations) > 0 && annotations[TolerationsAnnotationKey] != "" { - err := json.Unmarshal([]byte(annotations[TolerationsAnnotationKey]), &tolerations) +func GetTolerationsFromPodAnnotations(annotations map[string]string) ([]api.Toleration, error) { + var tolerations []api.Toleration + if len(annotations) > 0 && annotations[api.TolerationsAnnotationKey] != "" { + err := json.Unmarshal([]byte(annotations[api.TolerationsAnnotationKey]), &tolerations) if err != nil { return tolerations, err } @@ -444,10 +423,10 @@ func GetTolerationsFromPodAnnotations(annotations map[string]string) ([]Tolerati // AddOrUpdateTolerationInPod tries to add a toleration to the pod's toleration list. // 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 - var newTolerations []Toleration + var newTolerations []api.Toleration updated := false for i := range podTolerations { if toleration.MatchToleration(&podTolerations[i]) { @@ -470,18 +449,8 @@ func AddOrUpdateTolerationInPod(pod *Pod, toleration *Toleration) bool { return true } -// MatchToleration checks if the toleration matches tolerationToMatch. Tolerations are unique by , -// if the two tolerations have same 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. -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 { return false } @@ -490,17 +459,17 @@ func TolerationToleratesTaint(toleration *Toleration, taint *Taint) bool { return false } // 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 } - if toleration.Operator == TolerationOpExists { + if toleration.Operator == api.TolerationOpExists { return true } return false } // 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 for i := range tolerations { if TolerationToleratesTaint(&tolerations[i], taint) { @@ -511,28 +480,14 @@ func TaintToleratedByTolerations(taint *Taint, tolerations []Toleration) bool { 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 // and converts it to the []Taint type in api. -func GetTaintsFromNodeAnnotations(annotations map[string]string) ([]Taint, error) { - var taints []Taint - if len(annotations) > 0 && annotations[TaintsAnnotationKey] != "" { - err := json.Unmarshal([]byte(annotations[TaintsAnnotationKey]), &taints) +func GetTaintsFromNodeAnnotations(annotations map[string]string) ([]api.Taint, error) { + var taints []api.Taint + if len(annotations) > 0 && annotations[api.TaintsAnnotationKey] != "" { + err := json.Unmarshal([]byte(annotations[api.TaintsAnnotationKey]), &taints) if err != nil { - return []Taint{}, err + return []api.Taint{}, err } } 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 // and a slice of unsafe Sysctls. This is only a convenience wrapper around // SysctlsFromPodAnnotation. -func SysctlsFromPodAnnotations(a map[string]string) ([]Sysctl, []Sysctl, error) { - safe, err := SysctlsFromPodAnnotation(a[SysctlsPodAnnotationKey]) +func SysctlsFromPodAnnotations(a map[string]string) ([]api.Sysctl, []api.Sysctl, error) { + safe, err := SysctlsFromPodAnnotation(a[api.SysctlsPodAnnotationKey]) if err != nil { return nil, nil, err } - unsafe, err := SysctlsFromPodAnnotation(a[UnsafeSysctlsPodAnnotationKey]) + unsafe, err := SysctlsFromPodAnnotation(a[api.UnsafeSysctlsPodAnnotationKey]) if err != nil { 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. -func SysctlsFromPodAnnotation(annotation string) ([]Sysctl, error) { +func SysctlsFromPodAnnotation(annotation string) ([]api.Sysctl, error) { if len(annotation) == 0 { return nil, nil } kvs := strings.Split(annotation, ",") - sysctls := make([]Sysctl, len(kvs)) + sysctls := make([]api.Sysctl, len(kvs)) for i, kv := range kvs { cs := strings.Split(kv, "=") 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. -func PodAnnotationsFromSysctls(sysctls []Sysctl) string { +func PodAnnotationsFromSysctls(sysctls []api.Sysctl) string { if len(sysctls) == 0 { return "" } @@ -589,10 +544,10 @@ func PodAnnotationsFromSysctls(sysctls []Sysctl) string { // GetAffinityFromPodAnnotations gets the json serialized affinity data from Pod.Annotations // and converts it to the Affinity type in api. // TODO: remove when alpha support for affinity is removed -func GetAffinityFromPodAnnotations(annotations map[string]string) (*Affinity, error) { - if len(annotations) > 0 && annotations[AffinityAnnotationKey] != "" { - var affinity Affinity - err := json.Unmarshal([]byte(annotations[AffinityAnnotationKey]), &affinity) +func GetAffinityFromPodAnnotations(annotations map[string]string) (*api.Affinity, error) { + if len(annotations) > 0 && annotations[api.AffinityAnnotationKey] != "" { + var affinity api.Affinity + err := json.Unmarshal([]byte(annotations[api.AffinityAnnotationKey]), &affinity) if err != nil { return nil, err } @@ -602,9 +557,9 @@ func GetAffinityFromPodAnnotations(annotations map[string]string) (*Affinity, er } // GetPersistentVolumeClass returns StorageClassName. -func GetPersistentVolumeClass(volume *PersistentVolume) string { +func GetPersistentVolumeClass(volume *api.PersistentVolume) string { // Use beta annotation first - if class, found := volume.Annotations[BetaStorageClassAnnotation]; found { + if class, found := volume.Annotations[api.BetaStorageClassAnnotation]; found { return class } @@ -613,9 +568,9 @@ func GetPersistentVolumeClass(volume *PersistentVolume) string { // GetPersistentVolumeClaimClass returns StorageClassName. If no storage class was // requested, it returns "". -func GetPersistentVolumeClaimClass(claim *PersistentVolumeClaim) string { +func GetPersistentVolumeClaimClass(claim *api.PersistentVolumeClaim) string { // Use beta annotation first - if class, found := claim.Annotations[BetaStorageClassAnnotation]; found { + if class, found := claim.Annotations[api.BetaStorageClassAnnotation]; found { return class } @@ -627,9 +582,9 @@ func GetPersistentVolumeClaimClass(claim *PersistentVolumeClaim) string { } // 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 - if _, found := claim.Annotations[BetaStorageClassAnnotation]; found { + if _, found := claim.Annotations[api.BetaStorageClassAnnotation]; found { return true } diff --git a/pkg/api/helper/helpers_test.go b/pkg/api/helper/helpers_test.go new file mode 100644 index 000000000000..45ed359a106f --- /dev/null +++ b/pkg/api/helper/helpers_test.go @@ -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) + } + } +} diff --git a/pkg/api/helpers_test.go b/pkg/api/helpers_test.go deleted file mode 100644 index 1b58690b5a1e..000000000000 --- a/pkg/api/helpers_test.go +++ /dev/null @@ -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) - } - } -} diff --git a/pkg/api/methods.go b/pkg/api/methods.go new file mode 100644 index 000000000000..b3bebfee18fd --- /dev/null +++ b/pkg/api/methods.go @@ -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 , +// if the two tolerations have same 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) +} diff --git a/pkg/api/methods_test.go b/pkg/api/methods_test.go new file mode 100644 index 000000000000..a52582b3543c --- /dev/null +++ b/pkg/api/methods_test.go @@ -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()) + } + } +} diff --git a/pkg/api/v1/BUILD b/pkg/api/v1/BUILD index de91276d3313..f08e35ec2093 100644 --- a/pkg/api/v1/BUILD +++ b/pkg/api/v1/BUILD @@ -31,6 +31,7 @@ go_library( tags = ["automanaged"], deps = [ "//pkg/api:go_default_library", + "//pkg/api/helper:go_default_library", "//pkg/apis/extensions:go_default_library", "//pkg/util:go_default_library", "//pkg/util/parsers:go_default_library", diff --git a/pkg/api/v1/helpers.go b/pkg/api/v1/helpers.go index 0308031e172c..4bbc31e27d98 100644 --- a/pkg/api/v1/helpers.go +++ b/pkg/api/v1/helpers.go @@ -28,6 +28,7 @@ import ( "k8s.io/apimachinery/pkg/util/sets" "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/helper" ) // IsOpaqueIntResourceName returns true if the resource name has the opaque @@ -285,7 +286,7 @@ func AddOrUpdateTolerationInPod(pod *Pod, toleration *Toleration) bool { updated := false for i := range podTolerations { if toleration.MatchToleration(&podTolerations[i]) { - if api.Semantic.DeepEqual(toleration, podTolerations[i]) { + if helper.Semantic.DeepEqual(toleration, podTolerations[i]) { return false } newTolerations = append(newTolerations, *toleration) @@ -527,7 +528,7 @@ func AddOrUpdateTaint(node *Node, taint *Taint) (*Node, bool, error) { updated := false for i := range nodeTaints { if taint.MatchTaint(&nodeTaints[i]) { - if api.Semantic.DeepEqual(taint, nodeTaints[i]) { + if helper.Semantic.DeepEqual(taint, nodeTaints[i]) { return newNode, false, nil } newTaints = append(newTaints, *taint) diff --git a/pkg/api/v1/validation/BUILD b/pkg/api/v1/validation/BUILD index e10b99099418..9417e3d3e0ff 100644 --- a/pkg/api/v1/validation/BUILD +++ b/pkg/api/v1/validation/BUILD @@ -12,7 +12,7 @@ go_library( srcs = ["validation.go"], tags = ["automanaged"], deps = [ - "//pkg/api:go_default_library", + "//pkg/api/helper:go_default_library", "//pkg/api/v1:go_default_library", "//vendor:k8s.io/apimachinery/pkg/api/resource", "//vendor:k8s.io/apimachinery/pkg/util/sets", diff --git a/pkg/api/v1/validation/validation.go b/pkg/api/v1/validation/validation.go index 6bb0099bfd42..c73f9ab2c865 100644 --- a/pkg/api/v1/validation/validation.go +++ b/pkg/api/v1/validation/validation.go @@ -24,7 +24,7 @@ import ( "k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/validation" "k8s.io/apimachinery/pkg/util/validation/field" - "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/helper" "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 { allErrs := validateResourceName(value, fldPath) 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")) } } @@ -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 { allErrs := field.ErrorList{} allErrs = append(allErrs, ValidateNonnegativeQuantity(value, fldPath)...) - if api.IsIntegerResourceName(resource) { + if helper.IsIntegerResourceName(resource) { if value.MilliValue()%int64(1000) != int64(0) { 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 !api.IsStandardResourceName(value) { + if !helper.IsStandardResourceName(value) { return append(allErrs, field.Invalid(fldPath, value, "must be a standard resource type or fully qualified")) } } diff --git a/pkg/api/validation/BUILD b/pkg/api/validation/BUILD index 2ba19cf44967..b524bd28eb9e 100644 --- a/pkg/api/validation/BUILD +++ b/pkg/api/validation/BUILD @@ -19,6 +19,7 @@ go_library( tags = ["automanaged"], deps = [ "//pkg/api:go_default_library", + "//pkg/api/helper:go_default_library", "//pkg/api/service:go_default_library", "//pkg/api/util:go_default_library", "//pkg/api/v1:go_default_library", @@ -67,6 +68,7 @@ go_test( tags = ["automanaged"], deps = [ "//pkg/api:go_default_library", + "//pkg/api/helper:go_default_library", "//pkg/api/service:go_default_library", "//pkg/api/testapi:go_default_library", "//pkg/api/testing:go_default_library", diff --git a/pkg/api/validation/validation.go b/pkg/api/validation/validation.go index ee2c4e7e7f94..4dc0ce0aa18f 100644 --- a/pkg/api/validation/validation.go +++ b/pkg/api/validation/validation.go @@ -41,6 +41,7 @@ import ( "k8s.io/apimachinery/pkg/util/validation/field" utilfeature "k8s.io/apiserver/pkg/util/feature" "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/helper" apiservice "k8s.io/kubernetes/pkg/api/service" "k8s.io/kubernetes/pkg/api/v1" "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, ValidateAppArmorPodAnnotations(annotations, spec, fldPath)...) - sysctls, err := api.SysctlsFromPodAnnotation(annotations[api.SysctlsPodAnnotationKey]) + sysctls, err := helper.SysctlsFromPodAnnotation(annotations[api.SysctlsPodAnnotationKey]) if err != nil { allErrs = append(allErrs, field.Invalid(fldPath.Key(api.SysctlsPodAnnotationKey), annotations[api.SysctlsPodAnnotationKey], err.Error())) } else { 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 { allErrs = append(allErrs, field.Invalid(fldPath.Key(api.UnsafeSysctlsPodAnnotationKey), annotations[api.UnsafeSysctlsPodAnnotationKey], err.Error())) } 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 { allErrs := field.ErrorList{} - tolerations, err := api.GetTolerationsFromPodAnnotations(annotations) + tolerations, err := helper.GetTolerationsFromPodAnnotations(annotations) if err != nil { allErrs = append(allErrs, field.Invalid(fldPath, api.TolerationsAnnotationKey, err.Error())) return allErrs @@ -156,7 +157,7 @@ func ValidateTolerationsInPodAnnotations(annotations map[string]string, fldPath func ValidateAffinityInPodAnnotations(annotations map[string]string, fldPath *field.Path) field.ErrorList { allErrs := field.ErrorList{} - affinity, err := api.GetAffinityFromPodAnnotations(annotations) + affinity, err := helper.GetAffinityFromPodAnnotations(annotations) if err != nil { allErrs = append(allErrs, field.Invalid(fldPath, api.AffinityAnnotationKey, err.Error())) 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())) } - if api.IsServiceIPSet(service) { + if helper.IsServiceIPSet(service) { 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")) } @@ -2958,7 +2959,7 @@ func ValidateReadOnlyPersistentDisks(volumes []api.Volume, fldPath *field.Path) func ValidateTaintsInNodeAnnotations(annotations map[string]string, fldPath *field.Path) field.ErrorList { allErrs := field.ErrorList{} - taints, err := api.GetTaintsFromNodeAnnotations(annotations) + taints, err := helper.GetTaintsFromNodeAnnotations(annotations) if err != nil { allErrs = append(allErrs, field.Invalid(fldPath, api.TaintsAnnotationKey, err.Error())) return allErrs @@ -3115,7 +3116,7 @@ func validateResourceName(value string, fldPath *field.Path) field.ErrorList { } 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")) } } @@ -3128,7 +3129,7 @@ func validateResourceName(value string, fldPath *field.Path) field.ErrorList { func validateContainerResourceName(value string, fldPath *field.Path) field.ErrorList { allErrs := validateResourceName(value, fldPath) 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")) } } @@ -3140,7 +3141,7 @@ func validateContainerResourceName(value string, fldPath *field.Path) field.Erro func ValidateResourceQuotaResourceName(value string, fldPath *field.Path) field.ErrorList { allErrs := validateResourceName(value, fldPath) if len(strings.Split(value, "/")) == 1 { - if !api.IsStandardQuotaResourceName(value) { + if !helper.IsStandardQuotaResourceName(value) { 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 !api.IsStandardLimitRangeType(value) { + if !helper.IsStandardLimitRangeType(value) { 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") scopeSet := sets.NewString() 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")) } 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")) } } @@ -3563,7 +3564,7 @@ func ValidateResourceQuotaSpec(resourceQuotaSpec *api.ResourceQuotaSpec, fld *fi func ValidateResourceQuantityValue(resource string, value resource.Quantity, fldPath *field.Path) field.ErrorList { allErrs := field.ErrorList{} allErrs = append(allErrs, ValidateNonnegativeQuantity(value, fldPath)...) - if api.IsIntegerResourceName(resource) { + if helper.IsIntegerResourceName(resource) { if value.MilliValue()%int64(1000) != int64(0) { 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 { allErrs := field.ErrorList{} 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")) } } diff --git a/pkg/api/validation/validation_test.go b/pkg/api/validation/validation_test.go index c96e79f07865..72fa9bf7de16 100644 --- a/pkg/api/validation/validation_test.go +++ b/pkg/api/validation/validation_test.go @@ -27,6 +27,7 @@ import ( "k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/validation/field" "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/helper" "k8s.io/kubernetes/pkg/api/service" "k8s.io/kubernetes/pkg/api/v1" "k8s.io/kubernetes/pkg/capabilities" @@ -3712,10 +3713,10 @@ func TestValidatePod(t *testing.T) { ImagePullPolicy: "IfNotPresent", Resources: api.ResourceRequirements{ Requests: api.ResourceList{ - api.OpaqueIntResourceName("A"): resource.MustParse("10"), + helper.OpaqueIntResourceName("A"): resource.MustParse("10"), }, Limits: api.ResourceList{ - api.OpaqueIntResourceName("A"): resource.MustParse("20"), + helper.OpaqueIntResourceName("A"): resource.MustParse("20"), }, }, TerminationMessagePolicy: "File", @@ -3737,10 +3738,10 @@ func TestValidatePod(t *testing.T) { ImagePullPolicy: "IfNotPresent", Resources: api.ResourceRequirements{ Requests: api.ResourceList{ - api.OpaqueIntResourceName("A"): resource.MustParse("10"), + helper.OpaqueIntResourceName("A"): resource.MustParse("10"), }, Limits: api.ResourceList{ - api.OpaqueIntResourceName("A"): resource.MustParse("20"), + helper.OpaqueIntResourceName("A"): resource.MustParse("20"), }, }, TerminationMessagePolicy: "File", @@ -4211,10 +4212,10 @@ func TestValidatePod(t *testing.T) { ImagePullPolicy: "IfNotPresent", Resources: api.ResourceRequirements{ Requests: api.ResourceList{ - api.OpaqueIntResourceName("A"): resource.MustParse("2"), + helper.OpaqueIntResourceName("A"): resource.MustParse("2"), }, 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", Resources: api.ResourceRequirements{ 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", Resources: api.ResourceRequirements{ 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", Resources: api.ResourceRequirements{ Requests: api.ResourceList{ - api.OpaqueIntResourceName("A"): resource.MustParse("5"), + helper.OpaqueIntResourceName("A"): resource.MustParse("5"), }, 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", Resources: api.ResourceRequirements{ Requests: api.ResourceList{ - api.OpaqueIntResourceName("A"): resource.MustParse("5"), + helper.OpaqueIntResourceName("A"): resource.MustParse("5"), }, 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{ api.ResourceName(api.ResourceCPU): resource.MustParse("10"), api.ResourceName(api.ResourceMemory): resource.MustParse("10G"), - api.OpaqueIntResourceName("A"): resource.MustParse("5"), - api.OpaqueIntResourceName("B"): resource.MustParse("10"), + helper.OpaqueIntResourceName("A"): resource.MustParse("5"), + helper.OpaqueIntResourceName("B"): resource.MustParse("10"), }, }, }, true}, @@ -6756,7 +6757,7 @@ func TestValidateNodeUpdate(t *testing.T) { Capacity: api.ResourceList{ api.ResourceName(api.ResourceCPU): resource.MustParse("10"), api.ResourceName(api.ResourceMemory): resource.MustParse("10G"), - api.OpaqueIntResourceName("A"): resource.MustParse("500m"), + helper.OpaqueIntResourceName("A"): resource.MustParse("500m"), }, }, }, false}, @@ -6772,12 +6773,12 @@ func TestValidateNodeUpdate(t *testing.T) { Capacity: api.ResourceList{ api.ResourceName(api.ResourceCPU): resource.MustParse("10"), api.ResourceName(api.ResourceMemory): resource.MustParse("10G"), - api.OpaqueIntResourceName("A"): resource.MustParse("5"), + helper.OpaqueIntResourceName("A"): resource.MustParse("5"), }, Allocatable: api.ResourceList{ api.ResourceName(api.ResourceCPU): resource.MustParse("10"), api.ResourceName(api.ResourceMemory): resource.MustParse("10G"), - api.OpaqueIntResourceName("A"): resource.MustParse("4.5"), + helper.OpaqueIntResourceName("A"): resource.MustParse("4.5"), }, }, }, false}, diff --git a/pkg/api/zz_generated.deepcopy.go b/pkg/api/zz_generated.deepcopy.go index 3b9fdbba8d95..b3430b97d341 100644 --- a/pkg/api/zz_generated.deepcopy.go +++ b/pkg/api/zz_generated.deepcopy.go @@ -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_ContainerStateWaiting, InType: reflect.TypeOf(&ContainerStateWaiting{})}, 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_DeleteOptions, InType: reflect.TypeOf(&DeleteOptions{})}, 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 { { in := in.(*DaemonEndpoint) diff --git a/pkg/controller/bootstrap/BUILD b/pkg/controller/bootstrap/BUILD index aca1a8aa2099..9f1b9a140a77 100644 --- a/pkg/controller/bootstrap/BUILD +++ b/pkg/controller/bootstrap/BUILD @@ -27,6 +27,7 @@ go_test( "//vendor:k8s.io/apimachinery/pkg/runtime/schema", "//vendor:k8s.io/client-go/kubernetes/fake", "//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/testing", ], diff --git a/pkg/controller/bootstrap/common_test.go b/pkg/controller/bootstrap/common_test.go index 203b8d7b8882..4da2a0966e3b 100644 --- a/pkg/controller/bootstrap/common_test.go +++ b/pkg/controller/bootstrap/common_test.go @@ -22,7 +22,7 @@ import ( "github.com/davecgh/go-spew/spew" 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" core "k8s.io/client-go/testing" bootstrapapi "k8s.io/kubernetes/pkg/bootstrap/api" @@ -59,7 +59,7 @@ func verifyActions(t *testing.T, expected, actual []core.Action) { } 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)) continue } diff --git a/pkg/controller/node/BUILD b/pkg/controller/node/BUILD index ba15fb953957..93e6d2843112 100644 --- a/pkg/controller/node/BUILD +++ b/pkg/controller/node/BUILD @@ -24,6 +24,7 @@ go_library( tags = ["automanaged"], deps = [ "//pkg/api:go_default_library", + "//pkg/api/helper:go_default_library", "//pkg/api/v1:go_default_library", "//pkg/client/clientset_generated/clientset:go_default_library", "//pkg/client/informers/informers_generated/externalversions/core/v1:go_default_library", diff --git a/pkg/controller/node/taint_controller.go b/pkg/controller/node/taint_controller.go index f82f0a4cde26..ae34da0d5e11 100644 --- a/pkg/controller/node/taint_controller.go +++ b/pkg/controller/node/taint_controller.go @@ -22,6 +22,7 @@ import ( "time" "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/helper" "k8s.io/kubernetes/pkg/api/v1" "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 } - 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 } updateItem := &podUpdateItem{ @@ -274,7 +275,7 @@ func (tc *NoExecuteTaintManager) NodeUpdated(oldNode *v1.Node, newNode *v1.Node) } newTaints = getNoExecuteTaints(newTaints) - if oldNode != nil && newNode != nil && api.Semantic.DeepEqual(oldTaints, newTaints) { + if oldNode != nil && newNode != nil && helper.Semantic.DeepEqual(oldTaints, newTaints) { return } updateItem := &nodeUpdateItem{ diff --git a/pkg/kubectl/BUILD b/pkg/kubectl/BUILD index c00d430a773b..fd408d1099f3 100644 --- a/pkg/kubectl/BUILD +++ b/pkg/kubectl/BUILD @@ -51,6 +51,7 @@ go_library( "//federation/apis/federation/v1beta1:go_default_library", "//pkg/api:go_default_library", "//pkg/api/annotations:go_default_library", + "//pkg/api/helper:go_default_library", "//pkg/api/util:go_default_library", "//pkg/api/v1:go_default_library", "//pkg/apis/apps:go_default_library", @@ -139,6 +140,7 @@ go_test( deps = [ "//federation/apis/federation/v1beta1:go_default_library", "//pkg/api:go_default_library", + "//pkg/api/helper:go_default_library", "//pkg/api/testapi:go_default_library", "//pkg/api/testing:go_default_library", "//pkg/api/v1:go_default_library", diff --git a/pkg/kubectl/cmd/BUILD b/pkg/kubectl/cmd/BUILD index a1835d966c77..a98a7ceba604 100644 --- a/pkg/kubectl/cmd/BUILD +++ b/pkg/kubectl/cmd/BUILD @@ -68,6 +68,7 @@ go_library( deps = [ "//pkg/api:go_default_library", "//pkg/api/annotations:go_default_library", + "//pkg/api/helper:go_default_library", "//pkg/api/v1:go_default_library", "//pkg/api/validation:go_default_library", "//pkg/apis/apps/v1beta1:go_default_library", diff --git a/pkg/kubectl/cmd/logs.go b/pkg/kubectl/cmd/logs.go index 924de401cd01..cf19ab033d33 100644 --- a/pkg/kubectl/cmd/logs.go +++ b/pkg/kubectl/cmd/logs.go @@ -29,6 +29,7 @@ import ( "k8s.io/apimachinery/pkg/runtime" restclient "k8s.io/client-go/rest" "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/helper" "k8s.io/kubernetes/pkg/api/validation" "k8s.io/kubernetes/pkg/kubectl/cmd/templates" 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"), } 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 { return err } diff --git a/pkg/kubectl/cmd/rollingupdate.go b/pkg/kubectl/cmd/rollingupdate.go index 400def364d99..0d021b5ff7b8 100644 --- a/pkg/kubectl/cmd/rollingupdate.go +++ b/pkg/kubectl/cmd/rollingupdate.go @@ -33,6 +33,7 @@ import ( utilerrors "k8s.io/apimachinery/pkg/util/errors" "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/helper" "k8s.io/kubernetes/pkg/api/v1" "k8s.io/kubernetes/pkg/kubectl" "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 // and adding the 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 { return err } diff --git a/pkg/kubectl/rolling_updater.go b/pkg/kubectl/rolling_updater.go index 06be0b85279f..70e72da1c4b5 100644 --- a/pkg/kubectl/rolling_updater.go +++ b/pkg/kubectl/rolling_updater.go @@ -32,6 +32,7 @@ import ( "k8s.io/apimachinery/pkg/util/wait" "k8s.io/client-go/util/integer" "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/helper" "k8s.io/kubernetes/pkg/api/v1" coreclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/internalversion" "k8s.io/kubernetes/pkg/client/retry" @@ -625,7 +626,7 @@ func CreateNewControllerFromCurrentController(rcClient coreclient.ReplicationCon newRc.Spec.Template.Spec.Containers[containerIndex].ImagePullPolicy = cfg.PullPolicy } - newHash, err := api.HashObject(newRc, codec) + newHash, err := helper.HashObject(newRc, codec) if err != nil { return nil, err } diff --git a/pkg/kubectl/rolling_updater_test.go b/pkg/kubectl/rolling_updater_test.go index cd6c858491c2..34ebdc738eb8 100644 --- a/pkg/kubectl/rolling_updater_test.go +++ b/pkg/kubectl/rolling_updater_test.go @@ -37,6 +37,7 @@ import ( manualfake "k8s.io/client-go/rest/fake" testcore "k8s.io/client-go/testing" "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/helper" "k8s.io/kubernetes/pkg/api/testapi" apitesting "k8s.io/kubernetes/pkg/api/testing" "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" @@ -1076,7 +1077,7 @@ func TestRollingUpdater_multipleContainersInPod(t *testing.T) { codec := testapi.Default.Codec() - deploymentHash, err := api.HashObject(test.newRc, codec) + deploymentHash, err := helper.HashObject(test.newRc, codec) if err != nil { t.Errorf("unexpected error: %v", err) } diff --git a/pkg/kubelet/config/BUILD b/pkg/kubelet/config/BUILD index 5a7b4713b57b..9e1d2cfebdd2 100644 --- a/pkg/kubelet/config/BUILD +++ b/pkg/kubelet/config/BUILD @@ -23,6 +23,7 @@ go_library( tags = ["automanaged"], deps = [ "//pkg/api:go_default_library", + "//pkg/api/helper:go_default_library", "//pkg/api/v1:go_default_library", "//pkg/api/v1/pod:go_default_library", "//pkg/api/validation:go_default_library", diff --git a/pkg/kubelet/config/common.go b/pkg/kubelet/config/common.go index ae594fec2218..93957d2b82eb 100644 --- a/pkg/kubelet/config/common.go +++ b/pkg/kubelet/config/common.go @@ -27,6 +27,7 @@ import ( "k8s.io/apimachinery/pkg/types" utilyaml "k8s.io/apimachinery/pkg/util/yaml" "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/helper" "k8s.io/kubernetes/pkg/api/v1" "k8s.io/kubernetes/pkg/api/validation" 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 { // Applying the default Taint tolerations to static pods, // so they are not evicted when there are node problems. - api.AddOrUpdateTolerationInPod(pod, &api.Toleration{ + helper.AddOrUpdateTolerationInPod(pod, &api.Toleration{ Operator: "Exists", Effect: api.TaintEffectNoExecute, }) diff --git a/pkg/printers/internalversion/BUILD b/pkg/printers/internalversion/BUILD index 18e7dfa067d0..b61945f61a98 100644 --- a/pkg/printers/internalversion/BUILD +++ b/pkg/printers/internalversion/BUILD @@ -62,6 +62,7 @@ go_library( "//pkg/api:go_default_library", "//pkg/api/annotations:go_default_library", "//pkg/api/events:go_default_library", + "//pkg/api/helper:go_default_library", "//pkg/apis/apps:go_default_library", "//pkg/apis/autoscaling:go_default_library", "//pkg/apis/batch:go_default_library", diff --git a/pkg/printers/internalversion/describe.go b/pkg/printers/internalversion/describe.go index 1be0c0f99063..199ca4d8a1a6 100644 --- a/pkg/printers/internalversion/describe.go +++ b/pkg/printers/internalversion/describe.go @@ -47,6 +47,7 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/annotations" "k8s.io/kubernetes/pkg/api/events" + "k8s.io/kubernetes/pkg/api/helper" "k8s.io/kubernetes/pkg/apis/apps" "k8s.io/kubernetes/pkg/apis/autoscaling" "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) printLabelsMultiline(w, "Labels", pv.Labels) 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) if pv.Spec.ClaimRef != nil { 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, "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, "Message:\t%s\n", pv.Status.Message) w.Write(LEVEL_0, "Source:\n") @@ -915,7 +916,7 @@ func (d *PersistentVolumeClaimDescriber) Describe(namespace, name string, descri capacity := "" accessModes := "" if pvc.Spec.VolumeName != "" { - accessModes = api.GetAccessModesAsString(pvc.Status.AccessModes) + accessModes = helper.GetAccessModesAsString(pvc.Status.AccessModes) storage = pvc.Status.Capacity[api.ResourceStorage] capacity = storage.String() } @@ -926,7 +927,7 @@ func (d *PersistentVolumeClaimDescriber) Describe(namespace, name string, descri w := NewPrefixWriter(out) w.Write(LEVEL_0, "Name:\t%s\n", pvc.Name) 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, "Volume:\t%s\n", pvc.Spec.VolumeName) printLabelsMultiline(w, "Labels", pvc.Labels) @@ -1225,7 +1226,7 @@ func describeVolumeClaimTemplates(templates []api.PersistentVolumeClaim, w Prefi w.Write(LEVEL_0, "Volume Claims:\n") for _, pvc := range templates { 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, " ", "Annotations", "\t", pvc.Annotations, sets.NewString()) if capacity, ok := pvc.Spec.Resources.Requests[api.ResourceStorage]; ok { diff --git a/pkg/printers/internalversion/printers.go b/pkg/printers/internalversion/printers.go index 57c6e779c399..b79dc4c40b79 100644 --- a/pkg/printers/internalversion/printers.go +++ b/pkg/printers/internalversion/printers.go @@ -32,6 +32,7 @@ import ( "k8s.io/kubernetes/federation/apis/federation" "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/events" + "k8s.io/kubernetes/pkg/api/helper" "k8s.io/kubernetes/pkg/apis/apps" "k8s.io/kubernetes/pkg/apis/autoscaling" "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 } - modesStr := api.GetAccessModesAsString(pv.Spec.AccessModes) + modesStr := helper.GetAccessModesAsString(pv.Spec.AccessModes) reclaimPolicyStr := string(pv.Spec.PersistentVolumeReclaimPolicy) aQty := pv.Spec.Capacity[api.ResourceStorage] @@ -1186,7 +1187,7 @@ func printPersistentVolume(pv *api.PersistentVolume, w io.Writer, options printe aSize, modesStr, reclaimPolicyStr, pv.Status.Phase, claimRefUID, - api.GetPersistentVolumeClass(pv), + helper.GetPersistentVolumeClass(pv), pv.Status.Reason, translateTimestamp(pv.CreationTimestamp), ); err != nil { @@ -1224,12 +1225,12 @@ func printPersistentVolumeClaim(pvc *api.PersistentVolumeClaim, w io.Writer, opt capacity := "" accessModes := "" if pvc.Spec.VolumeName != "" { - accessModes = api.GetAccessModesAsString(pvc.Status.AccessModes) + accessModes = helper.GetAccessModesAsString(pvc.Status.AccessModes) storage = pvc.Status.Capacity[api.ResourceStorage] 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 } if _, err := fmt.Fprint(w, AppendLabels(pvc.Labels, options.ColumnLabels)); err != nil { diff --git a/pkg/proxy/iptables/BUILD b/pkg/proxy/iptables/BUILD index e31f28b86be8..4e9f0072d53a 100644 --- a/pkg/proxy/iptables/BUILD +++ b/pkg/proxy/iptables/BUILD @@ -14,6 +14,7 @@ go_library( tags = ["automanaged"], deps = [ "//pkg/api:go_default_library", + "//pkg/api/helper:go_default_library", "//pkg/api/service:go_default_library", "//pkg/features:go_default_library", "//pkg/proxy:go_default_library", diff --git a/pkg/proxy/iptables/proxier.go b/pkg/proxy/iptables/proxier.go index 6913c976bad8..cb3edbae5951 100644 --- a/pkg/proxy/iptables/proxier.go +++ b/pkg/proxy/iptables/proxier.go @@ -42,6 +42,7 @@ import ( "k8s.io/client-go/tools/record" "k8s.io/client-go/util/flowcontrol" "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/helper" apiservice "k8s.io/kubernetes/pkg/api/service" "k8s.io/kubernetes/pkg/features" "k8s.io/kubernetes/pkg/proxy" @@ -172,7 +173,7 @@ func newServiceInfo(serviceName proxy.ServicePortName, port *api.ServicePort, se protocol: port.Protocol, nodePort: int(port.NodePort), // Deep-copy in case the service instance changes - loadBalancerStatus: *api.LoadBalancerStatusDeepCopy(&service.Status.LoadBalancer), + loadBalancerStatus: *helper.LoadBalancerStatusDeepCopy(&service.Status.LoadBalancer), sessionAffinityType: service.Spec.SessionAffinity, stickyMaxAgeMinutes: 180, // TODO: paramaterize this in the API. 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 !api.IsServiceIPSet(service) { + if !helper.IsServiceIPSet(service) { glog.V(3).Infof("Skipping service %s due to clusterIP = %q", svcName, service.Spec.ClusterIP) continue } diff --git a/pkg/proxy/userspace/BUILD b/pkg/proxy/userspace/BUILD index d58780bc6fdf..bd8ddfff36f1 100644 --- a/pkg/proxy/userspace/BUILD +++ b/pkg/proxy/userspace/BUILD @@ -22,6 +22,7 @@ go_library( tags = ["automanaged"], deps = [ "//pkg/api:go_default_library", + "//pkg/api/helper:go_default_library", "//pkg/proxy:go_default_library", "//pkg/proxy/util:go_default_library", "//pkg/util/exec:go_default_library", diff --git a/pkg/proxy/userspace/proxier.go b/pkg/proxy/userspace/proxier.go index c91db19419ec..52aeb410dd45 100644 --- a/pkg/proxy/userspace/proxier.go +++ b/pkg/proxy/userspace/proxier.go @@ -29,6 +29,7 @@ import ( "k8s.io/apimachinery/pkg/types" utilnet "k8s.io/apimachinery/pkg/util/net" "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/helper" "k8s.io/kubernetes/pkg/proxy" 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 for _, service := range services { // 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) continue } @@ -460,7 +461,7 @@ func (proxier *Proxier) OnServiceUpdate(services []*api.Service) { info.portal.port = int(servicePort.Port) info.externalIPs = service.Spec.ExternalIPs // 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.sessionAffinityType = service.Spec.SessionAffinity 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) { return false } - if !api.LoadBalancerStatusEqual(&info.loadBalancerStatus, &service.Status.LoadBalancer) { + if !helper.LoadBalancerStatusEqual(&info.loadBalancerStatus, &service.Status.LoadBalancer) { return false } if info.sessionAffinityType != service.Spec.SessionAffinity { diff --git a/pkg/proxy/winuserspace/BUILD b/pkg/proxy/winuserspace/BUILD index 77e619950459..e21993c9cb56 100644 --- a/pkg/proxy/winuserspace/BUILD +++ b/pkg/proxy/winuserspace/BUILD @@ -21,6 +21,7 @@ go_library( tags = ["automanaged"], deps = [ "//pkg/api:go_default_library", + "//pkg/api/helper:go_default_library", "//pkg/proxy:go_default_library", "//pkg/util/exec:go_default_library", "//pkg/util/ipconfig:go_default_library", diff --git a/pkg/proxy/winuserspace/proxier.go b/pkg/proxy/winuserspace/proxier.go index bbc25877ea58..b331530e7638 100644 --- a/pkg/proxy/winuserspace/proxier.go +++ b/pkg/proxy/winuserspace/proxier.go @@ -30,6 +30,7 @@ import ( utilnet "k8s.io/apimachinery/pkg/util/net" "k8s.io/apimachinery/pkg/util/runtime" "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/helper" "k8s.io/kubernetes/pkg/proxy" "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 for _, service := range services { // 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) continue } diff --git a/pkg/quota/evaluator/core/BUILD b/pkg/quota/evaluator/core/BUILD index 6da27aad59fd..d0c932db3769 100644 --- a/pkg/quota/evaluator/core/BUILD +++ b/pkg/quota/evaluator/core/BUILD @@ -24,6 +24,7 @@ go_library( tags = ["automanaged"], deps = [ "//pkg/api:go_default_library", + "//pkg/api/helper:go_default_library", "//pkg/api/v1:go_default_library", "//pkg/api/validation:go_default_library", "//pkg/client/clientset_generated/clientset:go_default_library", diff --git a/pkg/quota/evaluator/core/persistent_volume_claims.go b/pkg/quota/evaluator/core/persistent_volume_claims.go index 09ebb79c3ef2..fdea389a06c1 100644 --- a/pkg/quota/evaluator/core/persistent_volume_claims.go +++ b/pkg/quota/evaluator/core/persistent_volume_claims.go @@ -27,6 +27,7 @@ import ( "k8s.io/apimachinery/pkg/util/sets" "k8s.io/apiserver/pkg/admission" "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/helper" "k8s.io/kubernetes/pkg/api/v1" "k8s.io/kubernetes/pkg/client/clientset_generated/clientset" 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 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.ResourceRequestsStorage)) } @@ -175,7 +176,7 @@ func (p *pvcEvaluator) Usage(item runtime.Object) (api.ResourceList, error) { if err != nil { return result, err } - storageClassRef := api.GetPersistentVolumeClaimClass(pvc) + storageClassRef := helper.GetPersistentVolumeClaimClass(pvc) // charge for claim result[api.ResourcePersistentVolumeClaims] = resource.MustParse("1") diff --git a/pkg/registry/core/replicationcontroller/BUILD b/pkg/registry/core/replicationcontroller/BUILD index c783317f4124..25873e335885 100644 --- a/pkg/registry/core/replicationcontroller/BUILD +++ b/pkg/registry/core/replicationcontroller/BUILD @@ -18,6 +18,7 @@ go_library( tags = ["automanaged"], deps = [ "//pkg/api:go_default_library", + "//pkg/api/helper:go_default_library", "//pkg/api/validation:go_default_library", "//vendor:k8s.io/apimachinery/pkg/apis/meta/internalversion", "//vendor:k8s.io/apimachinery/pkg/apis/meta/v1", diff --git a/pkg/registry/core/replicationcontroller/strategy.go b/pkg/registry/core/replicationcontroller/strategy.go index 7bb3405b796b..d4d7cfebe268 100644 --- a/pkg/registry/core/replicationcontroller/strategy.go +++ b/pkg/registry/core/replicationcontroller/strategy.go @@ -34,6 +34,7 @@ import ( apistorage "k8s.io/apiserver/pkg/storage" "k8s.io/apiserver/pkg/storage/names" "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/helper" "k8s.io/kubernetes/pkg/api/validation" ) @@ -110,7 +111,7 @@ func (rcStrategy) ValidateUpdate(ctx genericapirequest.Context, obj, old runtime updateErrorList := validation.ValidateReplicationControllerUpdate(newRc, oldRc) errs := append(validationErrorList, updateErrorList...) - for key, value := range api.NonConvertibleFields(oldRc.Annotations) { + for key, value := range helper.NonConvertibleFields(oldRc.Annotations) { parts := strings.Split(key, "/") if len(parts) != 2 { continue diff --git a/pkg/registry/core/service/BUILD b/pkg/registry/core/service/BUILD index 46a26f6fb9f0..4a3f23851b86 100644 --- a/pkg/registry/core/service/BUILD +++ b/pkg/registry/core/service/BUILD @@ -20,6 +20,7 @@ go_library( tags = ["automanaged"], deps = [ "//pkg/api:go_default_library", + "//pkg/api/helper:go_default_library", "//pkg/api/service:go_default_library", "//pkg/api/validation:go_default_library", "//pkg/capabilities:go_default_library", diff --git a/pkg/registry/core/service/ipallocator/controller/BUILD b/pkg/registry/core/service/ipallocator/controller/BUILD index 9cc7e4dc4fb3..1b827aec11f7 100644 --- a/pkg/registry/core/service/ipallocator/controller/BUILD +++ b/pkg/registry/core/service/ipallocator/controller/BUILD @@ -14,6 +14,7 @@ go_library( tags = ["automanaged"], deps = [ "//pkg/api:go_default_library", + "//pkg/api/helper:go_default_library", "//pkg/client/clientset_generated/internalclientset/typed/core/internalversion:go_default_library", "//pkg/client/retry:go_default_library", "//pkg/registry/core/rangeallocation:go_default_library", diff --git a/pkg/registry/core/service/ipallocator/controller/repair.go b/pkg/registry/core/service/ipallocator/controller/repair.go index d5c9e8258f3e..a59e23e74f11 100644 --- a/pkg/registry/core/service/ipallocator/controller/repair.go +++ b/pkg/registry/core/service/ipallocator/controller/repair.go @@ -26,6 +26,7 @@ import ( "k8s.io/apimachinery/pkg/util/runtime" "k8s.io/apimachinery/pkg/util/wait" "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/helper" coreclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/internalversion" "k8s.io/kubernetes/pkg/client/retry" "k8s.io/kubernetes/pkg/registry/core/rangeallocation" @@ -128,7 +129,7 @@ func (c *Repair) runOnce() error { rebuilt := ipallocator.NewCIDRRange(c.network) // Check every Service's ClusterIP, and rebuild the state as we think it should be. for _, svc := range list.Items { - if !api.IsServiceIPSet(&svc) { + if !helper.IsServiceIPSet(&svc) { // didn't need a cluster IP continue } diff --git a/pkg/registry/core/service/rest.go b/pkg/registry/core/service/rest.go index 88f4891e458a..e4bc92afc74d 100644 --- a/pkg/registry/core/service/rest.go +++ b/pkg/registry/core/service/rest.go @@ -37,6 +37,7 @@ import ( "k8s.io/apiserver/pkg/registry/rest" utilfeature "k8s.io/apiserver/pkg/util/feature" "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/helper" apiservice "k8s.io/kubernetes/pkg/api/service" "k8s.io/kubernetes/pkg/api/validation" "k8s.io/kubernetes/pkg/features" @@ -87,13 +88,13 @@ func (rs *REST) Create(ctx genericapirequest.Context, obj runtime.Object) (runti releaseServiceIP := false defer func() { if releaseServiceIP { - if api.IsServiceIPSet(service) { + if helper.IsServiceIPSet(service) { rs.serviceIPs.Release(net.ParseIP(service.Spec.ClusterIP)) } } }() - if api.IsServiceIPRequested(service) { + if helper.IsServiceIPRequested(service) { // Allocate next available. ip, err := rs.serviceIPs.AllocateNext() if err != nil { @@ -104,7 +105,7 @@ func (rs *REST) Create(ctx genericapirequest.Context, obj runtime.Object) (runti } service.Spec.ClusterIP = ip.String() releaseServiceIP = true - } else if api.IsServiceIPSet(service) { + } else if helper.IsServiceIPSet(service) { // Try to respect the requested IP. if err := rs.serviceIPs.Allocate(net.ParseIP(service.Spec.ClusterIP)); err != nil { // 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 } - if api.IsServiceIPSet(service) { + if helper.IsServiceIPSet(service) { rs.serviceIPs.Release(net.ParseIP(service.Spec.ClusterIP)) } diff --git a/pkg/registry/rbac/reconciliation/BUILD b/pkg/registry/rbac/reconciliation/BUILD index 50c6dab9e05d..a3f22c2c8e46 100644 --- a/pkg/registry/rbac/reconciliation/BUILD +++ b/pkg/registry/rbac/reconciliation/BUILD @@ -17,7 +17,7 @@ go_test( library = ":go_default_library", tags = ["automanaged"], deps = [ - "//pkg/api:go_default_library", + "//pkg/api/helper:go_default_library", "//pkg/apis/rbac:go_default_library", "//vendor:k8s.io/apimachinery/pkg/apis/meta/v1", ], diff --git a/pkg/registry/rbac/reconciliation/reconcile_role_test.go b/pkg/registry/rbac/reconciliation/reconcile_role_test.go index 14712725ede2..9cd146648faa 100644 --- a/pkg/registry/rbac/reconciliation/reconcile_role_test.go +++ b/pkg/registry/rbac/reconciliation/reconcile_role_test.go @@ -20,7 +20,7 @@ import ( "testing" 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" ) @@ -268,7 +268,7 @@ func TestComputeReconciledRole(t *testing.T) { t.Errorf("%s: Expected\n\t%v\ngot\n\t%v", k, tc.expectedReconciliationNeeded, reconciliationNeeded) 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) } } diff --git a/pkg/registry/rbac/reconciliation/reconcile_rolebindings_test.go b/pkg/registry/rbac/reconciliation/reconcile_rolebindings_test.go index 9a69e9136bf4..b61b2540eebb 100644 --- a/pkg/registry/rbac/reconciliation/reconcile_rolebindings_test.go +++ b/pkg/registry/rbac/reconciliation/reconcile_rolebindings_test.go @@ -19,7 +19,7 @@ package reconciliation import ( "testing" - api "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/helper" "k8s.io/kubernetes/pkg/apis/rbac" ) @@ -81,10 +81,10 @@ func TestDiffObjectReferenceLists(t *testing.T) { for k, tc := range tests { 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) } - 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) } } @@ -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) 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) } } diff --git a/pkg/security/podsecuritypolicy/sysctl/BUILD b/pkg/security/podsecuritypolicy/sysctl/BUILD index 767ec5543db5..8c825ef9565c 100644 --- a/pkg/security/podsecuritypolicy/sysctl/BUILD +++ b/pkg/security/podsecuritypolicy/sysctl/BUILD @@ -17,6 +17,7 @@ go_library( tags = ["automanaged"], deps = [ "//pkg/api:go_default_library", + "//pkg/api/helper:go_default_library", "//vendor:k8s.io/apimachinery/pkg/util/validation/field", ], ) @@ -26,7 +27,10 @@ go_test( srcs = ["mustmatchpatterns_test.go"], library = ":go_default_library", tags = ["automanaged"], - deps = ["//pkg/api:go_default_library"], + deps = [ + "//pkg/api:go_default_library", + "//pkg/api/helper:go_default_library", + ], ) filegroup( diff --git a/pkg/security/podsecuritypolicy/sysctl/mustmatchpatterns.go b/pkg/security/podsecuritypolicy/sysctl/mustmatchpatterns.go index e498c3c16f80..c6b5370895bf 100644 --- a/pkg/security/podsecuritypolicy/sysctl/mustmatchpatterns.go +++ b/pkg/security/podsecuritypolicy/sysctl/mustmatchpatterns.go @@ -22,6 +22,7 @@ import ( "k8s.io/apimachinery/pkg/util/validation/field" "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/helper" ) // 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) - sysctls, err := api.SysctlsFromPodAnnotation(pod.Annotations[key]) + sysctls, err := helper.SysctlsFromPodAnnotation(pod.Annotations[key]) if err != nil { allErrs = append(allErrs, field.Invalid(fieldPath, pod.Annotations[key], err.Error())) } diff --git a/pkg/security/podsecuritypolicy/sysctl/mustmatchpatterns_test.go b/pkg/security/podsecuritypolicy/sysctl/mustmatchpatterns_test.go index 6ae87ada9fdb..f8aef3df102d 100644 --- a/pkg/security/podsecuritypolicy/sysctl/mustmatchpatterns_test.go +++ b/pkg/security/podsecuritypolicy/sysctl/mustmatchpatterns_test.go @@ -20,6 +20,7 @@ import ( "testing" "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/helper" ) func TestValidate(t *testing.T) { @@ -75,7 +76,7 @@ func TestValidate(t *testing.T) { } testAllowed := func(key string, category string) { pod.Annotations = map[string]string{ - key: api.PodAnnotationsFromSysctls(sysctls), + key: helper.PodAnnotationsFromSysctls(sysctls), } errs = strategy.Validate(pod) if len(errs) != 0 { @@ -85,7 +86,7 @@ func TestValidate(t *testing.T) { testDisallowed := func(key string, category string) { for _, s := range v.disallowed { 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) if len(errs) == 0 { diff --git a/plugin/pkg/admission/defaulttolerationseconds/BUILD b/plugin/pkg/admission/defaulttolerationseconds/BUILD index 76b2a305c576..5852adbdf945 100644 --- a/plugin/pkg/admission/defaulttolerationseconds/BUILD +++ b/plugin/pkg/admission/defaulttolerationseconds/BUILD @@ -15,6 +15,7 @@ go_test( tags = ["automanaged"], deps = [ "//pkg/api:go_default_library", + "//pkg/api/helper:go_default_library", "//vendor:k8s.io/apimachinery/pkg/apis/meta/v1", "//vendor:k8s.io/apiserver/pkg/admission", ], @@ -26,6 +27,7 @@ go_library( tags = ["automanaged"], deps = [ "//pkg/api:go_default_library", + "//pkg/api/helper:go_default_library", "//vendor:k8s.io/apimachinery/pkg/api/errors", "//vendor:k8s.io/apimachinery/pkg/apis/meta/v1", "//vendor:k8s.io/apiserver/pkg/admission", diff --git a/plugin/pkg/admission/defaulttolerationseconds/admission.go b/plugin/pkg/admission/defaulttolerationseconds/admission.go index ec0060121b1a..210cf787ae7c 100644 --- a/plugin/pkg/admission/defaulttolerationseconds/admission.go +++ b/plugin/pkg/admission/defaulttolerationseconds/admission.go @@ -25,6 +25,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apiserver/pkg/admission" "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/helper" ) var ( @@ -97,7 +98,7 @@ func (p *plugin) Admit(attributes admission.Attributes) (err error) { } if !toleratesNodeNotReady { - api.AddOrUpdateTolerationInPod(pod, &api.Toleration{ + helper.AddOrUpdateTolerationInPod(pod, &api.Toleration{ Key: metav1.TaintNodeNotReady, Operator: api.TolerationOpExists, Effect: api.TaintEffectNoExecute, @@ -106,7 +107,7 @@ func (p *plugin) Admit(attributes admission.Attributes) (err error) { } if !toleratesNodeUnreachable { - api.AddOrUpdateTolerationInPod(pod, &api.Toleration{ + helper.AddOrUpdateTolerationInPod(pod, &api.Toleration{ Key: metav1.TaintNodeUnreachable, Operator: api.TolerationOpExists, Effect: api.TaintEffectNoExecute, diff --git a/plugin/pkg/admission/defaulttolerationseconds/admission_test.go b/plugin/pkg/admission/defaulttolerationseconds/admission_test.go index eed602adf180..76fb78eb1f5d 100644 --- a/plugin/pkg/admission/defaulttolerationseconds/admission_test.go +++ b/plugin/pkg/admission/defaulttolerationseconds/admission_test.go @@ -22,6 +22,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apiserver/pkg/admission" "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/helper" ) 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) } - 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) } } diff --git a/plugin/pkg/admission/security/podsecuritypolicy/BUILD b/plugin/pkg/admission/security/podsecuritypolicy/BUILD index 2ccef94ab34a..071312ecc1eb 100644 --- a/plugin/pkg/admission/security/podsecuritypolicy/BUILD +++ b/plugin/pkg/admission/security/podsecuritypolicy/BUILD @@ -39,6 +39,7 @@ go_test( tags = ["automanaged"], deps = [ "//pkg/api:go_default_library", + "//pkg/api/helper:go_default_library", "//pkg/apis/extensions:go_default_library", "//pkg/client/informers/informers_generated/internalversion:go_default_library", "//pkg/client/listers/extensions/internalversion:go_default_library", diff --git a/plugin/pkg/admission/security/podsecuritypolicy/admission_test.go b/plugin/pkg/admission/security/podsecuritypolicy/admission_test.go index 2a87b3ac54fc..e8767b15d82f 100644 --- a/plugin/pkg/admission/security/podsecuritypolicy/admission_test.go +++ b/plugin/pkg/admission/security/podsecuritypolicy/admission_test.go @@ -31,6 +31,7 @@ import ( "k8s.io/apiserver/pkg/authentication/user" "k8s.io/apiserver/pkg/authorization/authorizer" kapi "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/helper" "k8s.io/kubernetes/pkg/apis/extensions" informers "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion" extensionslisters "k8s.io/kubernetes/pkg/client/listers/extensions/internalversion" @@ -1172,8 +1173,8 @@ func TestAdmitSysctls(t *testing.T) { } return sysctls } - pod.Annotations[kapi.SysctlsPodAnnotationKey] = kapi.PodAnnotationsFromSysctls(dummySysctls(safeSysctls)) - pod.Annotations[kapi.UnsafeSysctlsPodAnnotationKey] = kapi.PodAnnotationsFromSysctls(dummySysctls(unsafeSysctls)) + pod.Annotations[kapi.SysctlsPodAnnotationKey] = helper.PodAnnotationsFromSysctls(dummySysctls(safeSysctls)) + pod.Annotations[kapi.UnsafeSysctlsPodAnnotationKey] = helper.PodAnnotationsFromSysctls(dummySysctls(unsafeSysctls)) return pod } @@ -1319,7 +1320,7 @@ func TestAdmitSysctls(t *testing.T) { } for k, v := range tests { - origSafeSysctls, origUnsafeSysctls, err := kapi.SysctlsFromPodAnnotations(v.pod.Annotations) + origSafeSysctls, origUnsafeSysctls, err := helper.SysctlsFromPodAnnotations(v.pod.Annotations) if err != nil { 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) if v.shouldPass { - safeSysctls, unsafeSysctls, _ := kapi.SysctlsFromPodAnnotations(v.pod.Annotations) + safeSysctls, unsafeSysctls, _ := helper.SysctlsFromPodAnnotations(v.pod.Annotations) if !reflect.DeepEqual(safeSysctls, origSafeSysctls) { t.Errorf("%s: wrong safe sysctls: expected=%v, got=%v", k, origSafeSysctls, safeSysctls) } diff --git a/plugin/pkg/admission/storageclass/default/BUILD b/plugin/pkg/admission/storageclass/default/BUILD index f68808f27857..2d1d2c5b68a7 100644 --- a/plugin/pkg/admission/storageclass/default/BUILD +++ b/plugin/pkg/admission/storageclass/default/BUILD @@ -14,6 +14,7 @@ go_library( tags = ["automanaged"], deps = [ "//pkg/api:go_default_library", + "//pkg/api/helper:go_default_library", "//pkg/apis/storage:go_default_library", "//pkg/apis/storage/util:go_default_library", "//pkg/client/informers/informers_generated/internalversion:go_default_library", diff --git a/plugin/pkg/admission/storageclass/default/admission.go b/plugin/pkg/admission/storageclass/default/admission.go index de141fe76629..2a0a8e53d335 100644 --- a/plugin/pkg/admission/storageclass/default/admission.go +++ b/plugin/pkg/admission/storageclass/default/admission.go @@ -26,6 +26,7 @@ import ( "k8s.io/apimachinery/pkg/labels" admission "k8s.io/apiserver/pkg/admission" api "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/helper" "k8s.io/kubernetes/pkg/apis/storage" storageutil "k8s.io/kubernetes/pkg/apis/storage/util" informers "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion" @@ -96,7 +97,7 @@ func (c *claimDefaulterPlugin) Admit(a admission.Attributes) error { return nil } - if api.PersistentVolumeClaimHasClass(pvc) { + if helper.PersistentVolumeClaimHasClass(pvc) { // The user asked for a class. return nil } diff --git a/staging/src/k8s.io/client-go/pkg/api/annotation_key_constants.go b/staging/src/k8s.io/client-go/pkg/api/annotation_key_constants.go index 07732451f901..30331f982d30 100644 --- a/staging/src/k8s.io/client-go/pkg/api/annotation_key_constants.go +++ b/staging/src/k8s.io/client-go/pkg/api/annotation_key_constants.go @@ -64,4 +64,7 @@ const ( // in the Annotations of a Pod. // TODO: remove when alpha support for affinity is removed AffinityAnnotationKey string = "scheduler.alpha.kubernetes.io/affinity" + + // annotation key prefix used to identify non-convertible json paths. + NonConvertibleAnnotationPrefix = "non-convertible.kubernetes.io" ) diff --git a/staging/src/k8s.io/client-go/pkg/api/helpers.go b/staging/src/k8s.io/client-go/pkg/api/helper/helpers.go similarity index 60% rename from staging/src/k8s.io/client-go/pkg/api/helpers.go rename to staging/src/k8s.io/client-go/pkg/api/helper/helpers.go index f7e7afbdbc40..073890b7a905 100644 --- a/staging/src/k8s.io/client-go/pkg/api/helpers.go +++ b/staging/src/k8s.io/client-go/pkg/api/helper/helpers.go @@ -14,18 +14,15 @@ See the License for the specific language governing permissions and limitations under the License. */ -package api +package helper import ( "crypto/md5" "encoding/json" "fmt" - "reflect" "strings" "time" - "github.com/davecgh/go-spew/spew" - "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/conversion" @@ -34,25 +31,7 @@ import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/selection" "k8s.io/apimachinery/pkg/util/sets" -) - -// 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" + "k8s.io/client-go/pkg/api" ) // 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 { nonConvertibleKeys := map[string]string{} for key, value := range annotations { - if strings.HasPrefix(key, NonConvertibleAnnotationPrefix) { + if strings.HasPrefix(key, api.NonConvertibleAnnotationPrefix) { nonConvertibleKeys[key] = value } } @@ -89,10 +68,10 @@ var Semantic = conversion.EqualitiesOrDie( ) var standardResourceQuotaScopes = sets.NewString( - string(ResourceQuotaScopeTerminating), - string(ResourceQuotaScopeNotTerminating), - string(ResourceQuotaScopeBestEffort), - string(ResourceQuotaScopeNotBestEffort), + string(api.ResourceQuotaScopeTerminating), + string(api.ResourceQuotaScopeNotTerminating), + string(api.ResourceQuotaScopeBestEffort), + string(api.ResourceQuotaScopeNotBestEffort), ) // IsStandardResourceQuotaScope returns true if the scope is a standard value @@ -101,24 +80,24 @@ func IsStandardResourceQuotaScope(str string) bool { } var podObjectCountQuotaResources = sets.NewString( - string(ResourcePods), + string(api.ResourcePods), ) var podComputeQuotaResources = sets.NewString( - string(ResourceCPU), - string(ResourceMemory), - string(ResourceLimitsCPU), - string(ResourceLimitsMemory), - string(ResourceRequestsCPU), - string(ResourceRequestsMemory), + string(api.ResourceCPU), + string(api.ResourceMemory), + string(api.ResourceLimitsCPU), + string(api.ResourceLimitsMemory), + string(api.ResourceRequestsCPU), + string(api.ResourceRequestsMemory), ) // IsResourceQuotaScopeValidForResource returns true if the resource applies to the specified scope -func IsResourceQuotaScopeValidForResource(scope ResourceQuotaScope, resource string) bool { +func IsResourceQuotaScopeValidForResource(scope api.ResourceQuotaScope, resource string) bool { switch scope { - case ResourceQuotaScopeTerminating, ResourceQuotaScopeNotTerminating, ResourceQuotaScopeNotBestEffort: + case api.ResourceQuotaScopeTerminating, api.ResourceQuotaScopeNotTerminating, api.ResourceQuotaScopeNotBestEffort: return podObjectCountQuotaResources.Has(resource) || podComputeQuotaResources.Has(resource) - case ResourceQuotaScopeBestEffort: + case api.ResourceQuotaScopeBestEffort: return podObjectCountQuotaResources.Has(resource) default: return true @@ -126,8 +105,8 @@ func IsResourceQuotaScopeValidForResource(scope ResourceQuotaScope, resource str } var standardContainerResources = sets.NewString( - string(ResourceCPU), - string(ResourceMemory), + string(api.ResourceCPU), + string(api.ResourceMemory), ) // 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 // integer resource prefix. -func IsOpaqueIntResourceName(name ResourceName) bool { - return strings.HasPrefix(string(name), ResourceOpaqueIntPrefix) +func IsOpaqueIntResourceName(name api.ResourceName) bool { + return strings.HasPrefix(string(name), api.ResourceOpaqueIntPrefix) } // OpaqueIntResourceName returns a ResourceName with the canonical opaque // integer prefix prepended. If the argument already has the prefix, it is // returned unmodified. -func OpaqueIntResourceName(name string) ResourceName { - if IsOpaqueIntResourceName(ResourceName(name)) { - return ResourceName(name) +func OpaqueIntResourceName(name string) api.ResourceName { + if IsOpaqueIntResourceName(api.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( - string(LimitTypePod), - string(LimitTypeContainer), - string(LimitTypePersistentVolumeClaim), + string(api.LimitTypePod), + string(api.LimitTypeContainer), + string(api.LimitTypePersistentVolumeClaim), ) // IsStandardLimitRangeType returns true if the type is Pod or Container @@ -164,22 +143,22 @@ func IsStandardLimitRangeType(str string) bool { } var standardQuotaResources = sets.NewString( - string(ResourceCPU), - string(ResourceMemory), - string(ResourceRequestsCPU), - string(ResourceRequestsMemory), - string(ResourceRequestsStorage), - string(ResourceLimitsCPU), - string(ResourceLimitsMemory), - string(ResourcePods), - string(ResourceQuotas), - string(ResourceServices), - string(ResourceReplicationControllers), - string(ResourceSecrets), - string(ResourcePersistentVolumeClaims), - string(ResourceConfigMaps), - string(ResourceServicesNodePorts), - string(ResourceServicesLoadBalancers), + string(api.ResourceCPU), + string(api.ResourceMemory), + string(api.ResourceRequestsCPU), + string(api.ResourceRequestsMemory), + string(api.ResourceRequestsStorage), + string(api.ResourceLimitsCPU), + string(api.ResourceLimitsMemory), + string(api.ResourcePods), + string(api.ResourceQuotas), + string(api.ResourceServices), + string(api.ResourceReplicationControllers), + string(api.ResourceSecrets), + string(api.ResourcePersistentVolumeClaims), + string(api.ResourceConfigMaps), + string(api.ResourceServicesNodePorts), + string(api.ResourceServicesLoadBalancers), ) // IsStandardQuotaResourceName returns true if the resource is known to @@ -189,21 +168,21 @@ func IsStandardQuotaResourceName(str string) bool { } var standardResources = sets.NewString( - string(ResourceCPU), - string(ResourceMemory), - string(ResourceRequestsCPU), - string(ResourceRequestsMemory), - string(ResourceLimitsCPU), - string(ResourceLimitsMemory), - string(ResourcePods), - string(ResourceQuotas), - string(ResourceServices), - string(ResourceReplicationControllers), - string(ResourceSecrets), - string(ResourceConfigMaps), - string(ResourcePersistentVolumeClaims), - string(ResourceStorage), - string(ResourceRequestsStorage), + string(api.ResourceCPU), + string(api.ResourceMemory), + string(api.ResourceRequestsCPU), + string(api.ResourceRequestsMemory), + string(api.ResourceLimitsCPU), + string(api.ResourceLimitsMemory), + string(api.ResourcePods), + string(api.ResourceQuotas), + string(api.ResourceServices), + string(api.ResourceReplicationControllers), + string(api.ResourceSecrets), + string(api.ResourceConfigMaps), + string(api.ResourcePersistentVolumeClaims), + string(api.ResourceStorage), + string(api.ResourceRequestsStorage), ) // IsStandardResourceName returns true if the resource is known to the system @@ -212,50 +191,50 @@ func IsStandardResourceName(str string) bool { } var integerResources = sets.NewString( - string(ResourcePods), - string(ResourceQuotas), - string(ResourceServices), - string(ResourceReplicationControllers), - string(ResourceSecrets), - string(ResourceConfigMaps), - string(ResourcePersistentVolumeClaims), - string(ResourceServicesNodePorts), - string(ResourceServicesLoadBalancers), + string(api.ResourcePods), + string(api.ResourceQuotas), + string(api.ResourceServices), + string(api.ResourceReplicationControllers), + string(api.ResourceSecrets), + string(api.ResourceConfigMaps), + string(api.ResourcePersistentVolumeClaims), + string(api.ResourceServicesNodePorts), + string(api.ResourceServicesLoadBalancers), ) // IsIntegerResourceName returns true if the resource is measured in integer values func IsIntegerResourceName(str string) bool { - return integerResources.Has(str) || 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 // the objective is not to perform validation here -func IsServiceIPSet(service *Service) bool { - return service.Spec.ClusterIP != ClusterIPNone && service.Spec.ClusterIP != "" +func IsServiceIPSet(service *api.Service) bool { + return service.Spec.ClusterIP != api.ClusterIPNone && service.Spec.ClusterIP != "" } // this function aims to check if the service's cluster IP is requested or not -func IsServiceIPRequested(service *Service) bool { +func IsServiceIPRequested(service *api.Service) bool { // 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 service.Spec.ClusterIP == "" } var standardFinalizers = sets.NewString( - string(FinalizerKubernetes), + string(api.FinalizerKubernetes), metav1.FinalizerOrphanDependents, ) // 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] return found } // 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 { 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, // 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 { exists := false for _, existing := range *addresses { @@ -292,11 +271,11 @@ func HashObject(obj runtime.Object, codec runtime.Codec) (string, error) { } // TODO: make method on LoadBalancerStatus? -func LoadBalancerStatusEqual(l, r *LoadBalancerStatus) bool { +func LoadBalancerStatusEqual(l, r *api.LoadBalancerStatus) bool { return ingressSliceEqual(l.Ingress, r.Ingress) } -func ingressSliceEqual(lhs, rhs []LoadBalancerIngress) bool { +func ingressSliceEqual(lhs, rhs []api.LoadBalancerIngress) bool { if len(lhs) != len(rhs) { return false } @@ -308,7 +287,7 @@ func ingressSliceEqual(lhs, rhs []LoadBalancerIngress) bool { return true } -func ingressEqual(lhs, rhs *LoadBalancerIngress) bool { +func ingressEqual(lhs, rhs *api.LoadBalancerIngress) bool { if lhs.IP != rhs.IP { return false } @@ -319,9 +298,9 @@ func ingressEqual(lhs, rhs *LoadBalancerIngress) bool { } // TODO: make method on LoadBalancerStatus? -func LoadBalancerStatusDeepCopy(lb *LoadBalancerStatus) *LoadBalancerStatus { - c := &LoadBalancerStatus{} - c.Ingress = make([]LoadBalancerIngress, len(lb.Ingress)) +func LoadBalancerStatusDeepCopy(lb *api.LoadBalancerStatus) *api.LoadBalancerStatus { + c := &api.LoadBalancerStatus{} + c.Ingress = make([]api.LoadBalancerIngress, len(lb.Ingress)) for i := range lb.Ingress { c.Ingress[i] = lb.Ingress[i] } @@ -330,42 +309,42 @@ func LoadBalancerStatusDeepCopy(lb *LoadBalancerStatus) *LoadBalancerStatus { // GetAccessModesAsString returns a string representation of an array of access modes. // modes, when present, are always in the same order: RWO,ROX,RWX. -func GetAccessModesAsString(modes []PersistentVolumeAccessMode) string { +func GetAccessModesAsString(modes []api.PersistentVolumeAccessMode) string { modes = removeDuplicateAccessModes(modes) modesStr := []string{} - if containsAccessMode(modes, ReadWriteOnce) { + if containsAccessMode(modes, api.ReadWriteOnce) { modesStr = append(modesStr, "RWO") } - if containsAccessMode(modes, ReadOnlyMany) { + if containsAccessMode(modes, api.ReadOnlyMany) { modesStr = append(modesStr, "ROX") } - if containsAccessMode(modes, ReadWriteMany) { + if containsAccessMode(modes, api.ReadWriteMany) { modesStr = append(modesStr, "RWX") } return strings.Join(modesStr, ",") } // GetAccessModesAsString returns an array of AccessModes from a string created by GetAccessModesAsString -func GetAccessModesFromString(modes string) []PersistentVolumeAccessMode { +func GetAccessModesFromString(modes string) []api.PersistentVolumeAccessMode { strmodes := strings.Split(modes, ",") - accessModes := []PersistentVolumeAccessMode{} + accessModes := []api.PersistentVolumeAccessMode{} for _, s := range strmodes { s = strings.Trim(s, " ") switch { case s == "RWO": - accessModes = append(accessModes, ReadWriteOnce) + accessModes = append(accessModes, api.ReadWriteOnce) case s == "ROX": - accessModes = append(accessModes, ReadOnlyMany) + accessModes = append(accessModes, api.ReadOnlyMany) case s == "RWX": - accessModes = append(accessModes, ReadWriteMany) + accessModes = append(accessModes, api.ReadWriteMany) } } return accessModes } // removeDuplicateAccessModes returns an array of access modes without any duplicates -func removeDuplicateAccessModes(modes []PersistentVolumeAccessMode) []PersistentVolumeAccessMode { - accessModes := []PersistentVolumeAccessMode{} +func removeDuplicateAccessModes(modes []api.PersistentVolumeAccessMode) []api.PersistentVolumeAccessMode { + accessModes := []api.PersistentVolumeAccessMode{} for _, m := range modes { if !containsAccessMode(accessModes, m) { accessModes = append(accessModes, m) @@ -374,7 +353,7 @@ func removeDuplicateAccessModes(modes []PersistentVolumeAccessMode) []Persistent return accessModes } -func containsAccessMode(modes []PersistentVolumeAccessMode, mode PersistentVolumeAccessMode) bool { +func containsAccessMode(modes []api.PersistentVolumeAccessMode, mode api.PersistentVolumeAccessMode) bool { for _, m := range modes { if m == mode { 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 // labels.Selector. -func NodeSelectorRequirementsAsSelector(nsm []NodeSelectorRequirement) (labels.Selector, error) { +func NodeSelectorRequirementsAsSelector(nsm []api.NodeSelectorRequirement) (labels.Selector, error) { if len(nsm) == 0 { return labels.Nothing(), nil } @@ -405,17 +384,17 @@ func NodeSelectorRequirementsAsSelector(nsm []NodeSelectorRequirement) (labels.S for _, expr := range nsm { var op selection.Operator switch expr.Operator { - case NodeSelectorOpIn: + case api.NodeSelectorOpIn: op = selection.In - case NodeSelectorOpNotIn: + case api.NodeSelectorOpNotIn: op = selection.NotIn - case NodeSelectorOpExists: + case api.NodeSelectorOpExists: op = selection.Exists - case NodeSelectorOpDoesNotExist: + case api.NodeSelectorOpDoesNotExist: op = selection.DoesNotExist - case NodeSelectorOpGt: + case api.NodeSelectorOpGt: op = selection.GreaterThan - case NodeSelectorOpLt: + case api.NodeSelectorOpLt: op = selection.LessThan default: 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 // and converts it to the []Toleration type in api. -func GetTolerationsFromPodAnnotations(annotations map[string]string) ([]Toleration, error) { - var tolerations []Toleration - if len(annotations) > 0 && annotations[TolerationsAnnotationKey] != "" { - err := json.Unmarshal([]byte(annotations[TolerationsAnnotationKey]), &tolerations) +func GetTolerationsFromPodAnnotations(annotations map[string]string) ([]api.Toleration, error) { + var tolerations []api.Toleration + if len(annotations) > 0 && annotations[api.TolerationsAnnotationKey] != "" { + err := json.Unmarshal([]byte(annotations[api.TolerationsAnnotationKey]), &tolerations) if err != nil { return tolerations, err } @@ -444,10 +423,10 @@ func GetTolerationsFromPodAnnotations(annotations map[string]string) ([]Tolerati // AddOrUpdateTolerationInPod tries to add a toleration to the pod's toleration list. // 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 - var newTolerations []Toleration + var newTolerations []api.Toleration updated := false for i := range podTolerations { if toleration.MatchToleration(&podTolerations[i]) { @@ -470,18 +449,8 @@ func AddOrUpdateTolerationInPod(pod *Pod, toleration *Toleration) bool { return true } -// MatchToleration checks if the toleration matches tolerationToMatch. Tolerations are unique by , -// if the two tolerations have same 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. -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 { return false } @@ -490,17 +459,17 @@ func TolerationToleratesTaint(toleration *Toleration, taint *Taint) bool { return false } // 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 } - if toleration.Operator == TolerationOpExists { + if toleration.Operator == api.TolerationOpExists { return true } return false } // 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 for i := range tolerations { if TolerationToleratesTaint(&tolerations[i], taint) { @@ -511,28 +480,14 @@ func TaintToleratedByTolerations(taint *Taint, tolerations []Toleration) bool { 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 // and converts it to the []Taint type in api. -func GetTaintsFromNodeAnnotations(annotations map[string]string) ([]Taint, error) { - var taints []Taint - if len(annotations) > 0 && annotations[TaintsAnnotationKey] != "" { - err := json.Unmarshal([]byte(annotations[TaintsAnnotationKey]), &taints) +func GetTaintsFromNodeAnnotations(annotations map[string]string) ([]api.Taint, error) { + var taints []api.Taint + if len(annotations) > 0 && annotations[api.TaintsAnnotationKey] != "" { + err := json.Unmarshal([]byte(annotations[api.TaintsAnnotationKey]), &taints) if err != nil { - return []Taint{}, err + return []api.Taint{}, err } } 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 // and a slice of unsafe Sysctls. This is only a convenience wrapper around // SysctlsFromPodAnnotation. -func SysctlsFromPodAnnotations(a map[string]string) ([]Sysctl, []Sysctl, error) { - safe, err := SysctlsFromPodAnnotation(a[SysctlsPodAnnotationKey]) +func SysctlsFromPodAnnotations(a map[string]string) ([]api.Sysctl, []api.Sysctl, error) { + safe, err := SysctlsFromPodAnnotation(a[api.SysctlsPodAnnotationKey]) if err != nil { return nil, nil, err } - unsafe, err := SysctlsFromPodAnnotation(a[UnsafeSysctlsPodAnnotationKey]) + unsafe, err := SysctlsFromPodAnnotation(a[api.UnsafeSysctlsPodAnnotationKey]) if err != nil { 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. -func SysctlsFromPodAnnotation(annotation string) ([]Sysctl, error) { +func SysctlsFromPodAnnotation(annotation string) ([]api.Sysctl, error) { if len(annotation) == 0 { return nil, nil } kvs := strings.Split(annotation, ",") - sysctls := make([]Sysctl, len(kvs)) + sysctls := make([]api.Sysctl, len(kvs)) for i, kv := range kvs { cs := strings.Split(kv, "=") 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. -func PodAnnotationsFromSysctls(sysctls []Sysctl) string { +func PodAnnotationsFromSysctls(sysctls []api.Sysctl) string { if len(sysctls) == 0 { return "" } @@ -589,10 +544,10 @@ func PodAnnotationsFromSysctls(sysctls []Sysctl) string { // GetAffinityFromPodAnnotations gets the json serialized affinity data from Pod.Annotations // and converts it to the Affinity type in api. // TODO: remove when alpha support for affinity is removed -func GetAffinityFromPodAnnotations(annotations map[string]string) (*Affinity, error) { - if len(annotations) > 0 && annotations[AffinityAnnotationKey] != "" { - var affinity Affinity - err := json.Unmarshal([]byte(annotations[AffinityAnnotationKey]), &affinity) +func GetAffinityFromPodAnnotations(annotations map[string]string) (*api.Affinity, error) { + if len(annotations) > 0 && annotations[api.AffinityAnnotationKey] != "" { + var affinity api.Affinity + err := json.Unmarshal([]byte(annotations[api.AffinityAnnotationKey]), &affinity) if err != nil { return nil, err } @@ -602,9 +557,9 @@ func GetAffinityFromPodAnnotations(annotations map[string]string) (*Affinity, er } // GetPersistentVolumeClass returns StorageClassName. -func GetPersistentVolumeClass(volume *PersistentVolume) string { +func GetPersistentVolumeClass(volume *api.PersistentVolume) string { // Use beta annotation first - if class, found := volume.Annotations[BetaStorageClassAnnotation]; found { + if class, found := volume.Annotations[api.BetaStorageClassAnnotation]; found { return class } @@ -613,9 +568,9 @@ func GetPersistentVolumeClass(volume *PersistentVolume) string { // GetPersistentVolumeClaimClass returns StorageClassName. If no storage class was // requested, it returns "". -func GetPersistentVolumeClaimClass(claim *PersistentVolumeClaim) string { +func GetPersistentVolumeClaimClass(claim *api.PersistentVolumeClaim) string { // Use beta annotation first - if class, found := claim.Annotations[BetaStorageClassAnnotation]; found { + if class, found := claim.Annotations[api.BetaStorageClassAnnotation]; found { return class } @@ -627,9 +582,9 @@ func GetPersistentVolumeClaimClass(claim *PersistentVolumeClaim) string { } // 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 - if _, found := claim.Annotations[BetaStorageClassAnnotation]; found { + if _, found := claim.Annotations[api.BetaStorageClassAnnotation]; found { return true } diff --git a/staging/src/k8s.io/client-go/pkg/api/methods.go b/staging/src/k8s.io/client-go/pkg/api/methods.go new file mode 100644 index 000000000000..b3bebfee18fd --- /dev/null +++ b/staging/src/k8s.io/client-go/pkg/api/methods.go @@ -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 , +// if the two tolerations have same 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) +} diff --git a/staging/src/k8s.io/client-go/pkg/api/v1/helpers.go b/staging/src/k8s.io/client-go/pkg/api/v1/helpers.go index 340ba63a4df7..05764e4cea27 100644 --- a/staging/src/k8s.io/client-go/pkg/api/v1/helpers.go +++ b/staging/src/k8s.io/client-go/pkg/api/v1/helpers.go @@ -28,6 +28,7 @@ import ( "k8s.io/apimachinery/pkg/util/sets" "k8s.io/client-go/pkg/api" + "k8s.io/client-go/pkg/api/helper" ) // IsOpaqueIntResourceName returns true if the resource name has the opaque @@ -285,7 +286,7 @@ func AddOrUpdateTolerationInPod(pod *Pod, toleration *Toleration) bool { updated := false for i := range podTolerations { if toleration.MatchToleration(&podTolerations[i]) { - if api.Semantic.DeepEqual(toleration, podTolerations[i]) { + if helper.Semantic.DeepEqual(toleration, podTolerations[i]) { return false } newTolerations = append(newTolerations, *toleration) @@ -527,7 +528,7 @@ func AddOrUpdateTaint(node *Node, taint *Taint) (*Node, bool, error) { updated := false for i := range nodeTaints { if taint.MatchTaint(&nodeTaints[i]) { - if api.Semantic.DeepEqual(taint, nodeTaints[i]) { + if helper.Semantic.DeepEqual(taint, nodeTaints[i]) { return newNode, false, nil } newTaints = append(newTaints, *taint) diff --git a/staging/src/k8s.io/client-go/pkg/api/zz_generated.deepcopy.go b/staging/src/k8s.io/client-go/pkg/api/zz_generated.deepcopy.go index 3b9fdbba8d95..b3430b97d341 100644 --- a/staging/src/k8s.io/client-go/pkg/api/zz_generated.deepcopy.go +++ b/staging/src/k8s.io/client-go/pkg/api/zz_generated.deepcopy.go @@ -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_ContainerStateWaiting, InType: reflect.TypeOf(&ContainerStateWaiting{})}, 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_DeleteOptions, InType: reflect.TypeOf(&DeleteOptions{})}, 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 { { in := in.(*DaemonEndpoint) diff --git a/test/integration/defaulttolerationseconds/defaulttolerationseconds_test.go b/test/integration/defaulttolerationseconds/defaulttolerationseconds_test.go index 948818ba110a..bc4f104d1119 100644 --- a/test/integration/defaulttolerationseconds/defaulttolerationseconds_test.go +++ b/test/integration/defaulttolerationseconds/defaulttolerationseconds_test.go @@ -24,6 +24,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" restclient "k8s.io/client-go/rest" "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/helper" "k8s.io/kubernetes/pkg/api/v1" "k8s.io/kubernetes/pkg/client/clientset_generated/clientset" "k8s.io/kubernetes/plugin/pkg/admission/defaulttolerationseconds" @@ -85,13 +86,13 @@ func TestAdmission(t *testing.T) { break } if tolerations[i].MatchToleration(&nodeNotReady) { - if api.Semantic.DeepEqual(tolerations[i], nodeNotReady) { + if helper.Semantic.DeepEqual(tolerations[i], nodeNotReady) { found++ continue } } if tolerations[i].MatchToleration(&nodeUnreachable) { - if api.Semantic.DeepEqual(tolerations[i], nodeUnreachable) { + if helper.Semantic.DeepEqual(tolerations[i], nodeUnreachable) { found++ continue } diff --git a/vendor/BUILD b/vendor/BUILD index a7ef60db89ee..91a57ca6618a 100644 --- a/vendor/BUILD +++ b/vendor/BUILD @@ -13889,8 +13889,8 @@ go_library( "k8s.io/client-go/pkg/api/defaults.go", "k8s.io/client-go/pkg/api/doc.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/methods.go", "k8s.io/client-go/pkg/api/ref.go", "k8s.io/client-go/pkg/api/register.go", "k8s.io/client-go/pkg/api/resource_helpers.go", @@ -13899,7 +13899,6 @@ go_library( ], tags = ["automanaged"], deps = [ - "//vendor:github.com/davecgh/go-spew/spew", "//vendor:k8s.io/apimachinery/pkg/api/meta", "//vendor:k8s.io/apimachinery/pkg/api/resource", "//vendor:k8s.io/apimachinery/pkg/apimachinery/announced", @@ -13911,10 +13910,8 @@ go_library( "//vendor:k8s.io/apimachinery/pkg/runtime", "//vendor:k8s.io/apimachinery/pkg/runtime/schema", "//vendor:k8s.io/apimachinery/pkg/runtime/serializer", - "//vendor:k8s.io/apimachinery/pkg/selection", "//vendor:k8s.io/apimachinery/pkg/types", "//vendor:k8s.io/apimachinery/pkg/util/intstr", - "//vendor:k8s.io/apimachinery/pkg/util/sets", ], ) @@ -13971,6 +13968,7 @@ go_library( "//vendor:k8s.io/apimachinery/pkg/util/sets", "//vendor:k8s.io/apimachinery/pkg/util/validation/field", "//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/util", "//vendor:k8s.io/client-go/pkg/util/parsers", @@ -16747,3 +16745,20 @@ filegroup( srcs = [":package-srcs"], 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", + ], +)