Merge pull request #85899 from gongguan/slim_down_lister

slim down some lister expansions
This commit is contained in:
Kubernetes Prow Robot 2019-12-09 07:20:17 -08:00 committed by GitHub
commit fcc35b0468
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
28 changed files with 419 additions and 351 deletions

View File

@ -231,7 +231,7 @@ func (dc *DeploymentController) addReplicaSet(obj interface{}) {
// getDeploymentsForReplicaSet returns a list of Deployments that potentially
// match a ReplicaSet.
func (dc *DeploymentController) getDeploymentsForReplicaSet(rs *apps.ReplicaSet) []*apps.Deployment {
deployments, err := dc.dLister.GetDeploymentsForReplicaSet(rs)
deployments, err := util.GetDeploymentsForReplicaSet(dc.dLister, rs)
if err != nil || len(deployments) == 0 {
return nil
}

View File

@ -18,11 +18,13 @@ go_library(
"//staging/src/k8s.io/apimachinery/pkg/api/equality:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/api/meta:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/intstr:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/wait:go_default_library",
"//staging/src/k8s.io/client-go/kubernetes/typed/apps/v1:go_default_library",
"//staging/src/k8s.io/client-go/listers/apps/v1:go_default_library",
"//vendor/k8s.io/klog:go_default_library",
"//vendor/k8s.io/utils/integer:go_default_library",
],
@ -46,6 +48,7 @@ go_test(
"//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/intstr:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/storage/names:go_default_library",
"//staging/src/k8s.io/client-go/informers:go_default_library",
"//staging/src/k8s.io/client-go/kubernetes/fake:go_default_library",
"//staging/src/k8s.io/client-go/testing:go_default_library",
],

View File

@ -24,18 +24,19 @@ import (
"strings"
"time"
"k8s.io/klog"
apps "k8s.io/api/apps/v1"
v1 "k8s.io/api/core/v1"
apiequality "k8s.io/apimachinery/pkg/api/equality"
"k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
intstrutil "k8s.io/apimachinery/pkg/util/intstr"
"k8s.io/apimachinery/pkg/util/wait"
appsclient "k8s.io/client-go/kubernetes/typed/apps/v1"
appslisters "k8s.io/client-go/listers/apps/v1"
"k8s.io/klog"
"k8s.io/kubernetes/pkg/controller"
labelsutil "k8s.io/kubernetes/pkg/util/labels"
"k8s.io/utils/integer"
@ -912,3 +913,38 @@ func HasProgressDeadline(d *apps.Deployment) bool {
func HasRevisionHistoryLimit(d *apps.Deployment) bool {
return d.Spec.RevisionHistoryLimit != nil && *d.Spec.RevisionHistoryLimit != math.MaxInt32
}
// GetDeploymentsForReplicaSet returns a list of Deployments that potentially
// match a ReplicaSet. Only the one specified in the ReplicaSet's ControllerRef
// will actually manage it.
// Returns an error only if no matching Deployments are found.
func GetDeploymentsForReplicaSet(deploymentLister appslisters.DeploymentLister, rs *apps.ReplicaSet) ([]*apps.Deployment, error) {
if len(rs.Labels) == 0 {
return nil, fmt.Errorf("no deployments found for ReplicaSet %v because it has no labels", rs.Name)
}
// TODO: MODIFY THIS METHOD so that it checks for the podTemplateSpecHash label
dList, err := deploymentLister.Deployments(rs.Namespace).List(labels.Everything())
if err != nil {
return nil, err
}
var deployments []*apps.Deployment
for _, d := range dList {
selector, err := metav1.LabelSelectorAsSelector(d.Spec.Selector)
if err != nil {
return nil, fmt.Errorf("invalid label selector: %v", err)
}
// If a deployment with a nil or empty selector creeps in, it should match nothing, not everything.
if selector.Empty() || !selector.Matches(labels.Set(rs.Labels)) {
continue
}
deployments = append(deployments, d)
}
if len(deployments) == 0 {
return nil, fmt.Errorf("could not find deployments set for ReplicaSet %s in namespace %s with labels: %v", rs.Name, rs.Namespace, rs.Labels)
}
return deployments, nil
}

View File

@ -34,6 +34,7 @@ import (
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/intstr"
"k8s.io/apiserver/pkg/storage/names"
"k8s.io/client-go/informers"
"k8s.io/client-go/kubernetes/fake"
core "k8s.io/client-go/testing"
"k8s.io/kubernetes/pkg/controller"
@ -1402,3 +1403,84 @@ func TestReplicasAnnotationsNeedUpdate(t *testing.T) {
})
}
}
func TestGetDeploymentsForReplicaSet(t *testing.T) {
fakeInformerFactory := informers.NewSharedInformerFactory(&fake.Clientset{}, 0*time.Second)
var deployments []*apps.Deployment
for i := 0; i < 3; i++ {
deployment := &apps.Deployment{
ObjectMeta: metav1.ObjectMeta{
Name: fmt.Sprintf("deployment-%d", i),
Namespace: "test",
},
Spec: apps.DeploymentSpec{
Selector: &metav1.LabelSelector{
MatchLabels: map[string]string{
"app": fmt.Sprintf("test-%d", i),
},
},
},
}
deployments = append(deployments, deployment)
fakeInformerFactory.Apps().V1().Deployments().Informer().GetStore().Add(deployment)
}
var rss []*apps.ReplicaSet
for i := 0; i < 5; i++ {
rs := &apps.ReplicaSet{
ObjectMeta: metav1.ObjectMeta{
Namespace: "test",
Name: fmt.Sprintf("test-replicaSet-%d", i),
Labels: map[string]string{
"app": fmt.Sprintf("test-%d", i),
"label": fmt.Sprintf("label-%d", i),
},
},
}
rss = append(rss, rs)
}
tests := []struct {
name string
rs *apps.ReplicaSet
err error
expect []*apps.Deployment
}{
{
name: "GetDeploymentsForReplicaSet for rs-0",
rs: rss[0],
expect: []*apps.Deployment{deployments[0]},
},
{
name: "GetDeploymentsForReplicaSet for rs-1",
rs: rss[1],
expect: []*apps.Deployment{deployments[1]},
},
{
name: "GetDeploymentsForReplicaSet for rs-2",
rs: rss[2],
expect: []*apps.Deployment{deployments[2]},
},
{
name: "GetDeploymentsForReplicaSet for rs-3",
rs: rss[3],
err: fmt.Errorf("could not find deployments set for ReplicaSet %s in namespace %s with labels: %v", rss[3].Name, rss[3].Namespace, rss[3].Labels),
},
{
name: "GetDeploymentsForReplicaSet for rs-4",
rs: rss[4],
err: fmt.Errorf("could not find deployments set for ReplicaSet %s in namespace %s with labels: %v", rss[4].Name, rss[4].Namespace, rss[4].Labels),
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
get, err := GetDeploymentsForReplicaSet(fakeInformerFactory.Apps().V1().Deployments().Lister(), test.rs)
if err != nil {
if err.Error() != test.err.Error() {
t.Errorf("Error from GetDeploymentsForReplicaSet: %v", err)
}
} else if !reflect.DeepEqual(get, test.expect) {
t.Errorf("Expect deployments %v, but got %v", test.expect, get)
}
})
}
}

View File

@ -12,6 +12,7 @@ go_library(
deps = [
"//staging/src/k8s.io/api/core/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/runtime:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",

View File

@ -26,6 +26,7 @@ import (
v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/util/runtime"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/apimachinery/pkg/util/wait"
@ -372,7 +373,7 @@ func (s *Controller) syncLoadBalancerIfNeeded(service *v1.Service, key string) (
}
func (s *Controller) ensureLoadBalancer(service *v1.Service) (*v1.LoadBalancerStatus, error) {
nodes, err := s.nodeLister.ListWithPredicate(getNodeConditionPredicate())
nodes, err := listWithPredicate(s.nodeLister, getNodeConditionPredicate())
if err != nil {
return nil, err
}
@ -601,7 +602,7 @@ func nodeSlicesEqualForLB(x, y []*v1.Node) bool {
return nodeNames(x).Equal(nodeNames(y))
}
func getNodeConditionPredicate() corelisters.NodeConditionPredicate {
func getNodeConditionPredicate() NodeConditionPredicate {
return func(node *v1.Node) bool {
// We add the master to the node list, but its unschedulable. So we use this to filter
// the master.
@ -645,7 +646,7 @@ func getNodeConditionPredicate() corelisters.NodeConditionPredicate {
// nodeSyncLoop handles updating the hosts pointed to by all load
// balancers whenever the set of nodes in the cluster changes.
func (s *Controller) nodeSyncLoop() {
newHosts, err := s.nodeLister.ListWithPredicate(getNodeConditionPredicate())
newHosts, err := listWithPredicate(s.nodeLister, getNodeConditionPredicate())
if err != nil {
runtime.HandleError(fmt.Errorf("Failed to retrieve current set of nodes from node lister: %v", err))
return
@ -847,3 +848,24 @@ func (s *Controller) patchStatus(service *v1.Service, previousStatus, newStatus
_, err := patch(s.kubeClient.CoreV1(), service, updated)
return err
}
// NodeConditionPredicate is a function that indicates whether the given node's conditions meet
// some set of criteria defined by the function.
type NodeConditionPredicate func(node *v1.Node) bool
// listWithPredicate gets nodes that matches predicate function.
func listWithPredicate(nodeLister corelisters.NodeLister, predicate NodeConditionPredicate) ([]*v1.Node, error) {
nodes, err := nodeLister.List(labels.Everything())
if err != nil {
return nil, err
}
var filtered []*v1.Node
for i := range nodes {
if predicate(nodes[i]) {
filtered = append(filtered, nodes[i])
}
}
return filtered, nil
}

View File

@ -21,6 +21,7 @@ import (
"errors"
"fmt"
"reflect"
"sort"
"strings"
"testing"
"time"
@ -1428,3 +1429,67 @@ func Test_getNodeConditionPredicate(t *testing.T) {
})
}
}
func TestListWithPredicate(t *testing.T) {
fakeInformerFactory := informers.NewSharedInformerFactory(&fake.Clientset{}, 0*time.Second)
var nodes []*v1.Node
for i := 0; i < 5; i++ {
var phase v1.NodePhase
if i%2 == 0 {
phase = v1.NodePending
} else {
phase = v1.NodeRunning
}
node := &v1.Node{
ObjectMeta: metav1.ObjectMeta{
Name: fmt.Sprintf("node-%d", i),
},
Status: v1.NodeStatus{
Phase: phase,
},
}
nodes = append(nodes, node)
fakeInformerFactory.Core().V1().Nodes().Informer().GetStore().Add(node)
}
tests := []struct {
name string
predicate NodeConditionPredicate
expect []*v1.Node
}{
{
name: "ListWithPredicate filter Running node",
predicate: func(node *v1.Node) bool {
return node.Status.Phase == v1.NodeRunning
},
expect: []*v1.Node{nodes[1], nodes[3]},
},
{
name: "ListWithPredicate filter Pending node",
predicate: func(node *v1.Node) bool {
return node.Status.Phase == v1.NodePending
},
expect: []*v1.Node{nodes[0], nodes[2], nodes[4]},
},
{
name: "ListWithPredicate filter Terminated node",
predicate: func(node *v1.Node) bool {
return node.Status.Phase == v1.NodeTerminated
},
expect: nil,
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
get, err := listWithPredicate(fakeInformerFactory.Core().V1().Nodes().Lister(), test.predicate)
sort.Slice(get, func(i, j int) bool {
return get[i].Name < get[j].Name
})
if err != nil {
t.Errorf("Error from ListWithPredicate: %v", err)
} else if !reflect.DeepEqual(get, test.expect) {
t.Errorf("Expect nodes %v, but got %v", test.expect, get)
}
})
}
}

View File

@ -243,7 +243,6 @@ go_test(
"//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
"//staging/src/k8s.io/client-go/kubernetes:go_default_library",
"//staging/src/k8s.io/client-go/kubernetes/fake:go_default_library",
"//staging/src/k8s.io/client-go/listers/core/v1:go_default_library",
"//staging/src/k8s.io/client-go/rest:go_default_library",
"//staging/src/k8s.io/client-go/testing:go_default_library",
"//staging/src/k8s.io/client-go/tools/record:go_default_library",

View File

@ -39,7 +39,6 @@ import (
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/apimachinery/pkg/util/wait"
"k8s.io/client-go/kubernetes/fake"
corelisters "k8s.io/client-go/listers/core/v1"
"k8s.io/client-go/tools/record"
"k8s.io/client-go/util/flowcontrol"
cadvisortest "k8s.io/kubernetes/pkg/kubelet/cadvisor/testing"
@ -446,10 +445,6 @@ func (nl testNodeLister) List(_ labels.Selector) (ret []*v1.Node, err error) {
return nl.nodes, nil
}
func (nl testNodeLister) ListWithPredicate(_ corelisters.NodeConditionPredicate) ([]*v1.Node, error) {
return nl.nodes, nil
}
func checkPodStatus(t *testing.T, kl *Kubelet, pod *v1.Pod, phase v1.PodPhase) {
status, found := kl.statusManager.GetPodStatus(pod.UID)
require.True(t, found, "Status of pod %q is not found in the status map", pod.UID)

View File

@ -1003,7 +1003,7 @@ func (s *ServiceAffinity) serviceAffinityMetadataProducer(pm *predicateMetadata)
return
}
// Store services which match the pod.
matchingPodServices, err := s.serviceLister.GetPodServices(pm.pod)
matchingPodServices, err := schedulerlisters.GetPodServices(s.serviceLister, pm.pod)
if err != nil {
klog.Errorf("Error precomputing service affinity: could not list services: %v", err)
}

View File

@ -105,7 +105,7 @@ func (pmf *MetadataFactory) PriorityMetadata(
// getFirstServiceSelector returns one selector of services the given pod.
func getFirstServiceSelector(pod *v1.Pod, sl corelisters.ServiceLister) (firstServiceSelector labels.Selector) {
if services, err := sl.GetPodServices(pod); err == nil && len(services) > 0 {
if services, err := schedulerlisters.GetPodServices(sl, pod); err == nil && len(services) > 0 {
return labels.SelectorFromSet(services[0].Spec.Selector)
}
return nil
@ -117,7 +117,7 @@ func getSelector(pod *v1.Pod, sl corelisters.ServiceLister, cl corelisters.Repli
// Since services, RCs, RSs and SSs match the pod, they won't have conflicting
// labels. Merging is safe.
if services, err := sl.GetPodServices(pod); err == nil {
if services, err := schedulerlisters.GetPodServices(sl, pod); err == nil {
for _, service := range services {
labelSet = labels.Merge(labelSet, service.Spec.Selector)
}

View File

@ -1,4 +1,4 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
go_library(
name = "go_default_library",
@ -9,6 +9,19 @@ go_library(
"//pkg/scheduler/nodeinfo:go_default_library",
"//staging/src/k8s.io/api/core/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library",
"//staging/src/k8s.io/client-go/listers/core/v1:go_default_library",
],
)
go_test(
name = "go_default_test",
srcs = ["listers_test.go"],
embed = [":go_default_library"],
deps = [
"//staging/src/k8s.io/api/core/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/client-go/informers:go_default_library",
"//staging/src/k8s.io/client-go/kubernetes/fake:go_default_library",
],
)

View File

@ -63,7 +63,16 @@ type ServiceLister []*v1.Service
// Services returns nil.
func (f ServiceLister) Services(namespace string) corelisters.ServiceNamespaceLister {
return nil
var services []*v1.Service
for i := range f {
if f[i].Namespace == namespace {
services = append(services, f[i])
}
}
return &serviceNamespaceLister{
services: services,
namespace: namespace,
}
}
// List returns v1.ServiceList, the list of all services.
@ -71,22 +80,18 @@ func (f ServiceLister) List(labels.Selector) ([]*v1.Service, error) {
return f, nil
}
// GetPodServices gets the services that have the selector that match the labels on the given pod.
func (f ServiceLister) GetPodServices(pod *v1.Pod) (services []*v1.Service, err error) {
var selector labels.Selector
// serviceNamespaceLister is implementation of ServiceNamespaceLister returned by Services() above.
type serviceNamespaceLister struct {
services []*v1.Service
namespace string
}
for i := range f {
service := f[i]
// consider only services that are in the same namespace as the pod
if service.Namespace != pod.Namespace {
continue
}
selector = labels.Set(service.Spec.Selector).AsSelectorPreValidated()
if selector.Matches(labels.Set(pod.Labels)) {
services = append(services, service)
}
}
return
func (f *serviceNamespaceLister) Get(name string) (*v1.Service, error) {
return nil, fmt.Errorf("not implemented")
}
func (f *serviceNamespaceLister) List(selector labels.Selector) ([]*v1.Service, error) {
return f.services, nil
}
var _ corelisters.ReplicationControllerLister = &ControllerLister{}

View File

@ -19,6 +19,7 @@ package listers
import (
v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/labels"
v1listers "k8s.io/client-go/listers/core/v1"
schedulernodeinfo "k8s.io/kubernetes/pkg/scheduler/nodeinfo"
)
@ -49,3 +50,27 @@ type SharedLister interface {
Pods() PodLister
NodeInfos() NodeInfoLister
}
// GetPodServices gets the services that have the selector that match the labels on the given pod.
// TODO: this should be moved to ServiceAffinity plugin once that plugin is ready.
func GetPodServices(serviceLister v1listers.ServiceLister, pod *v1.Pod) ([]*v1.Service, error) {
allServices, err := serviceLister.Services(pod.Namespace).List(labels.Everything())
if err != nil {
return nil, err
}
var services []*v1.Service
for i := range allServices {
service := allServices[i]
if service.Spec.Selector == nil {
// services with nil selectors match nothing, not everything.
continue
}
selector := labels.Set(service.Spec.Selector).AsSelectorPreValidated()
if selector.Matches(labels.Set(pod.Labels)) {
services = append(services, service)
}
}
return services, nil
}

View File

@ -0,0 +1,105 @@
/*
Copyright 2019 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 listers
import (
"fmt"
"reflect"
"testing"
"time"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/informers"
"k8s.io/client-go/kubernetes/fake"
)
func TestGetPodServices(t *testing.T) {
fakeInformerFactory := informers.NewSharedInformerFactory(&fake.Clientset{}, 0*time.Second)
var services []*v1.Service
for i := 0; i < 3; i++ {
service := &v1.Service{
ObjectMeta: metav1.ObjectMeta{
Name: fmt.Sprintf("service-%d", i),
Namespace: "test",
},
Spec: v1.ServiceSpec{
Selector: map[string]string{
"app": fmt.Sprintf("test-%d", i),
},
},
}
services = append(services, service)
fakeInformerFactory.Core().V1().Services().Informer().GetStore().Add(service)
}
var pods []*v1.Pod
for i := 0; i < 5; i++ {
pod := &v1.Pod{
ObjectMeta: metav1.ObjectMeta{
Namespace: "test",
Name: fmt.Sprintf("test-pod-%d", i),
Labels: map[string]string{
"app": fmt.Sprintf("test-%d", i),
"label": fmt.Sprintf("label-%d", i),
},
},
}
pods = append(pods, pod)
}
tests := []struct {
name string
pod *v1.Pod
expect []*v1.Service
}{
{
name: "GetPodServices for pod-0",
pod: pods[0],
expect: []*v1.Service{services[0]},
},
{
name: "GetPodServices for pod-1",
pod: pods[1],
expect: []*v1.Service{services[1]},
},
{
name: "GetPodServices for pod-2",
pod: pods[2],
expect: []*v1.Service{services[2]},
},
{
name: "GetPodServices for pod-3",
pod: pods[3],
expect: nil,
},
{
name: "GetPodServices for pod-4",
pod: pods[4],
expect: nil,
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
get, err := GetPodServices(fakeInformerFactory.Core().V1().Services().Lister(), test.pod)
if err != nil {
t.Errorf("Error from GetPodServices: %v", err)
} else if !reflect.DeepEqual(get, test.expect) {
t.Errorf("Expect services %v, but got %v", test.expect, get)
}
})
}
}

View File

@ -7,7 +7,6 @@ go_library(
"daemonset.go",
"daemonset_expansion.go",
"deployment.go",
"deployment_expansion.go",
"expansion_generated.go",
"replicaset.go",
"replicaset_expansion.go",

View File

@ -1,70 +0,0 @@
/*
Copyright 2017 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package v1
import (
"fmt"
apps "k8s.io/api/apps/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
)
// DeploymentListerExpansion allows custom methods to be added to
// DeploymentLister.
type DeploymentListerExpansion interface {
GetDeploymentsForReplicaSet(rs *apps.ReplicaSet) ([]*apps.Deployment, error)
}
// DeploymentNamespaceListerExpansion allows custom methods to be added to
// DeploymentNamespaceLister.
type DeploymentNamespaceListerExpansion interface{}
// GetDeploymentsForReplicaSet returns a list of Deployments that potentially
// match a ReplicaSet. Only the one specified in the ReplicaSet's ControllerRef
// will actually manage it.
// Returns an error only if no matching Deployments are found.
func (s *deploymentLister) GetDeploymentsForReplicaSet(rs *apps.ReplicaSet) ([]*apps.Deployment, error) {
if len(rs.Labels) == 0 {
return nil, fmt.Errorf("no deployments found for ReplicaSet %v because it has no labels", rs.Name)
}
// TODO: MODIFY THIS METHOD so that it checks for the podTemplateSpecHash label
dList, err := s.Deployments(rs.Namespace).List(labels.Everything())
if err != nil {
return nil, err
}
var deployments []*apps.Deployment
for _, d := range dList {
selector, err := metav1.LabelSelectorAsSelector(d.Spec.Selector)
if err != nil {
return nil, fmt.Errorf("invalid label selector: %v", err)
}
// If a deployment with a nil or empty selector creeps in, it should match nothing, not everything.
if selector.Empty() || !selector.Matches(labels.Set(rs.Labels)) {
continue
}
deployments = append(deployments, d)
}
if len(deployments) == 0 {
return nil, fmt.Errorf("could not find deployments set for ReplicaSet %s in namespace %s with labels: %v", rs.Name, rs.Namespace, rs.Labels)
}
return deployments, nil
}

View File

@ -25,3 +25,11 @@ type ControllerRevisionListerExpansion interface{}
// ControllerRevisionNamespaceListerExpansion allows custom methods to be added to
// ControllerRevisionNamespaceLister.
type ControllerRevisionNamespaceListerExpansion interface{}
// DeploymentListerExpansion allows custom methods to be added to
// DeploymentLister.
type DeploymentListerExpansion interface{}
// DeploymentNamespaceListerExpansion allows custom methods to be added to
// DeploymentNamespaceLister.
type DeploymentNamespaceListerExpansion interface{}

View File

@ -12,7 +12,6 @@ go_library(
"daemonset.go",
"daemonset_expansion.go",
"deployment.go",
"deployment_expansion.go",
"expansion_generated.go",
"replicaset.go",
"replicaset_expansion.go",

View File

@ -1,70 +0,0 @@
/*
Copyright 2017 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package v1beta2
import (
"fmt"
apps "k8s.io/api/apps/v1beta2"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
)
// DeploymentListerExpansion allows custom methods to be added to
// DeploymentLister.
type DeploymentListerExpansion interface {
GetDeploymentsForReplicaSet(rs *apps.ReplicaSet) ([]*apps.Deployment, error)
}
// DeploymentNamespaceListerExpansion allows custom methods to be added to
// DeploymentNamespaceLister.
type DeploymentNamespaceListerExpansion interface{}
// GetDeploymentsForReplicaSet returns a list of Deployments that potentially
// match a ReplicaSet. Only the one specified in the ReplicaSet's ControllerRef
// will actually manage it.
// Returns an error only if no matching Deployments are found.
func (s *deploymentLister) GetDeploymentsForReplicaSet(rs *apps.ReplicaSet) ([]*apps.Deployment, error) {
if len(rs.Labels) == 0 {
return nil, fmt.Errorf("no deployments found for ReplicaSet %v because it has no labels", rs.Name)
}
// TODO: MODIFY THIS METHOD so that it checks for the podTemplateSpecHash label
dList, err := s.Deployments(rs.Namespace).List(labels.Everything())
if err != nil {
return nil, err
}
var deployments []*apps.Deployment
for _, d := range dList {
selector, err := metav1.LabelSelectorAsSelector(d.Spec.Selector)
if err != nil {
return nil, fmt.Errorf("invalid label selector: %v", err)
}
// If a deployment with a nil or empty selector creeps in, it should match nothing, not everything.
if selector.Empty() || !selector.Matches(labels.Set(rs.Labels)) {
continue
}
deployments = append(deployments, d)
}
if len(deployments) == 0 {
return nil, fmt.Errorf("could not find deployments set for ReplicaSet %s in namespace %s with labels: %v", rs.Name, rs.Namespace, rs.Labels)
}
return deployments, nil
}

View File

@ -25,3 +25,11 @@ type ControllerRevisionListerExpansion interface{}
// ControllerRevisionNamespaceListerExpansion allows custom methods to be added to
// ControllerRevisionNamespaceLister.
type ControllerRevisionNamespaceListerExpansion interface{}
// DeploymentListerExpansion allows custom methods to be added to
// DeploymentLister.
type DeploymentListerExpansion interface{}
// DeploymentNamespaceListerExpansion allows custom methods to be added to
// DeploymentNamespaceLister.
type DeploymentNamespaceListerExpansion interface{}

View File

@ -16,7 +16,6 @@ go_library(
"limitrange.go",
"namespace.go",
"node.go",
"node_expansion.go",
"persistentvolume.go",
"persistentvolumeclaim.go",
"pod.go",
@ -26,7 +25,6 @@ go_library(
"resourcequota.go",
"secret.go",
"service.go",
"service_expansion.go",
"serviceaccount.go",
],
importmap = "k8s.io/kubernetes/vendor/k8s.io/client-go/listers/core/v1",

View File

@ -58,6 +58,10 @@ type LimitRangeNamespaceListerExpansion interface{}
// NamespaceLister.
type NamespaceListerExpansion interface{}
// NodeListerExpansion allows custom methods to be added to
// NodeLister.
type NodeListerExpansion interface{}
// PersistentVolumeListerExpansion allows custom methods to be added to
// PersistentVolumeLister.
type PersistentVolumeListerExpansion interface{}
@ -102,6 +106,14 @@ type SecretListerExpansion interface{}
// SecretNamespaceLister.
type SecretNamespaceListerExpansion interface{}
// ServiceListerExpansion allows custom methods to be added to
// ServiceLister.
type ServiceListerExpansion interface{}
// ServiceNamespaceListerExpansion allows custom methods to be added to
// ServiceNamespaceLister.
type ServiceNamespaceListerExpansion interface{}
// ServiceAccountListerExpansion allows custom methods to be added to
// ServiceAccountLister.
type ServiceAccountListerExpansion interface{}

View File

@ -1,48 +0,0 @@
/*
Copyright 2017 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package v1
import (
"k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/labels"
)
// NodeConditionPredicate is a function that indicates whether the given node's conditions meet
// some set of criteria defined by the function.
type NodeConditionPredicate func(node *v1.Node) bool
// NodeListerExpansion allows custom methods to be added to
// NodeLister.
type NodeListerExpansion interface {
ListWithPredicate(predicate NodeConditionPredicate) ([]*v1.Node, error)
}
func (l *nodeLister) ListWithPredicate(predicate NodeConditionPredicate) ([]*v1.Node, error) {
nodes, err := l.List(labels.Everything())
if err != nil {
return nil, err
}
var filtered []*v1.Node
for i := range nodes {
if predicate(nodes[i]) {
filtered = append(filtered, nodes[i])
}
}
return filtered, nil
}

View File

@ -1,56 +0,0 @@
/*
Copyright 2017 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package v1
import (
"k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/labels"
)
// ServiceListerExpansion allows custom methods to be added to
// ServiceLister.
type ServiceListerExpansion interface {
GetPodServices(pod *v1.Pod) ([]*v1.Service, error)
}
// ServiceNamespaceListerExpansion allows custom methods to be added to
// ServiceNamespaceLister.
type ServiceNamespaceListerExpansion interface{}
// TODO: Move this back to scheduler as a helper function that takes a Store,
// rather than a method of ServiceLister.
func (s *serviceLister) GetPodServices(pod *v1.Pod) ([]*v1.Service, error) {
allServices, err := s.Services(pod.Namespace).List(labels.Everything())
if err != nil {
return nil, err
}
var services []*v1.Service
for i := range allServices {
service := allServices[i]
if service.Spec.Selector == nil {
// services with nil selectors match nothing, not everything.
continue
}
selector := labels.Set(service.Spec.Selector).AsSelectorPreValidated()
if selector.Matches(labels.Set(pod.Labels)) {
services = append(services, service)
}
}
return services, nil
}

View File

@ -12,7 +12,6 @@ go_library(
"daemonset.go",
"daemonset_expansion.go",
"deployment.go",
"deployment_expansion.go",
"expansion_generated.go",
"ingress.go",
"networkpolicy.go",

View File

@ -1,70 +0,0 @@
/*
Copyright 2017 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package v1beta1
import (
"fmt"
extensions "k8s.io/api/extensions/v1beta1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
)
// DeploymentListerExpansion allows custom methods to be added to
// DeploymentLister.
type DeploymentListerExpansion interface {
GetDeploymentsForReplicaSet(rs *extensions.ReplicaSet) ([]*extensions.Deployment, error)
}
// DeploymentNamespaceListerExpansion allows custom methods to be added to
// DeploymentNamespaceLister.
type DeploymentNamespaceListerExpansion interface{}
// GetDeploymentsForReplicaSet returns a list of Deployments that potentially
// match a ReplicaSet. Only the one specified in the ReplicaSet's ControllerRef
// will actually manage it.
// Returns an error only if no matching Deployments are found.
func (s *deploymentLister) GetDeploymentsForReplicaSet(rs *extensions.ReplicaSet) ([]*extensions.Deployment, error) {
if len(rs.Labels) == 0 {
return nil, fmt.Errorf("no deployments found for ReplicaSet %v because it has no labels", rs.Name)
}
// TODO: MODIFY THIS METHOD so that it checks for the podTemplateSpecHash label
dList, err := s.Deployments(rs.Namespace).List(labels.Everything())
if err != nil {
return nil, err
}
var deployments []*extensions.Deployment
for _, d := range dList {
selector, err := metav1.LabelSelectorAsSelector(d.Spec.Selector)
if err != nil {
return nil, fmt.Errorf("invalid label selector: %v", err)
}
// If a deployment with a nil or empty selector creeps in, it should match nothing, not everything.
if selector.Empty() || !selector.Matches(labels.Set(rs.Labels)) {
continue
}
deployments = append(deployments, d)
}
if len(deployments) == 0 {
return nil, fmt.Errorf("could not find deployments set for ReplicaSet %s in namespace %s with labels: %v", rs.Name, rs.Namespace, rs.Labels)
}
return deployments, nil
}

View File

@ -18,6 +18,14 @@ limitations under the License.
package v1beta1
// DeploymentListerExpansion allows custom methods to be added to
// DeploymentLister.
type DeploymentListerExpansion interface{}
// DeploymentNamespaceListerExpansion allows custom methods to be added to
// DeploymentNamespaceLister.
type DeploymentNamespaceListerExpansion interface{}
// IngressListerExpansion allows custom methods to be added to
// IngressLister.
type IngressListerExpansion interface{}