mirror of https://github.com/linkerd/linkerd2.git
Add possibility to filter by owner and label in ListPods (#2161)
Signed-off-by: Alena Varkockova <varkockova.a@gmail.com>
This commit is contained in:
parent
ea61630f9d
commit
2691dda5ce
|
@ -72,6 +72,8 @@ func (*grpcServer) Version(ctx context.Context, req *pb.Empty) (*pb.VersionInfo,
|
|||
func (s *grpcServer) ListPods(ctx context.Context, req *pb.ListPodsRequest) (*pb.ListPodsResponse, error) {
|
||||
log.Debugf("ListPods request: %+v", req)
|
||||
|
||||
targetOwner := req.GetSelector().GetResource()
|
||||
|
||||
// Reports is a map from instance name to the absolute time of the most recent
|
||||
// report from that instance and its process start time
|
||||
reports := make(map[string]podReport)
|
||||
|
@ -80,14 +82,23 @@ func (s *grpcServer) ListPods(ctx context.Context, req *pb.ListPodsRequest) (*pb
|
|||
return nil, errors.New("cannot set both namespace and resource in the request. These are mutually exclusive")
|
||||
}
|
||||
|
||||
labelSelector := labels.Everything()
|
||||
if s := req.GetSelector().GetLabelSelector(); s != "" {
|
||||
var err error
|
||||
labelSelector, err = labels.Parse(s)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid label selector \"%s\": %s", s, err)
|
||||
}
|
||||
}
|
||||
|
||||
nsQuery := ""
|
||||
namespace := ""
|
||||
if req.GetNamespace() != "" {
|
||||
namespace = req.GetNamespace()
|
||||
} else if req.GetSelector().GetResource().GetNamespace() != "" {
|
||||
namespace = req.GetSelector().GetResource().GetNamespace()
|
||||
} else if req.GetSelector().GetResource().GetType() == pkgK8s.Namespace {
|
||||
namespace = req.GetSelector().GetResource().GetName()
|
||||
} else if targetOwner.GetNamespace() != "" {
|
||||
namespace = targetOwner.GetNamespace()
|
||||
} else if targetOwner.GetType() == pkgK8s.Namespace {
|
||||
namespace = targetOwner.GetName()
|
||||
}
|
||||
if namespace != "" {
|
||||
nsQuery = fmt.Sprintf("namespace=\"%s\"", namespace)
|
||||
|
@ -111,9 +122,9 @@ func (s *grpcServer) ListPods(ctx context.Context, req *pb.ListPodsRequest) (*pb
|
|||
|
||||
var pods []*k8sV1.Pod
|
||||
if namespace != "" {
|
||||
pods, err = s.k8sAPI.Pod().Lister().Pods(namespace).List(labels.Everything())
|
||||
pods, err = s.k8sAPI.Pod().Lister().Pods(namespace).List(labelSelector)
|
||||
} else {
|
||||
pods, err = s.k8sAPI.Pod().Lister().List(labels.Everything())
|
||||
pods, err = s.k8sAPI.Pod().Lister().List(labelSelector)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
|
@ -126,6 +137,18 @@ func (s *grpcServer) ListPods(ctx context.Context, req *pb.ListPodsRequest) (*pb
|
|||
continue
|
||||
}
|
||||
|
||||
ownerKind, ownerName := s.k8sAPI.GetOwnerKindAndName(pod)
|
||||
// filter out pods without matching owner
|
||||
if targetOwner.GetNamespace() != "" && targetOwner.GetNamespace() != pod.GetNamespace() {
|
||||
continue
|
||||
}
|
||||
if targetOwner.GetType() != "" && targetOwner.GetType() != ownerKind {
|
||||
continue
|
||||
}
|
||||
if targetOwner.GetName() != "" && targetOwner.GetName() != ownerName {
|
||||
continue
|
||||
}
|
||||
|
||||
updated, added := reports[pod.Name]
|
||||
|
||||
status := string(pod.Status.Phase)
|
||||
|
@ -162,7 +185,6 @@ func (s *grpcServer) ListPods(ctx context.Context, req *pb.ListPodsRequest) (*pb
|
|||
ProxyVersion: proxyVersion,
|
||||
}
|
||||
|
||||
ownerKind, ownerName := s.k8sAPI.GetOwnerKindAndName(pod)
|
||||
namespacedOwnerName := pod.Namespace + "/" + ownerName
|
||||
|
||||
switch ownerKind {
|
||||
|
|
|
@ -227,6 +227,166 @@ spec:
|
|||
res: &pb.ListPodsResponse{},
|
||||
promReqNamespace: "testnamespace",
|
||||
},
|
||||
// non-matching owner type -> no pod in the result
|
||||
listPodsExpected{
|
||||
err: nil,
|
||||
promRes: model.Vector{
|
||||
&model.Sample{
|
||||
Metric: model.Metric{"pod": "emojivoto-meshed"},
|
||||
Timestamp: 456,
|
||||
},
|
||||
},
|
||||
k8sRes: []string{`
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: emojivoto-meshed
|
||||
namespace: emojivoto
|
||||
labels:
|
||||
pod-template-hash: hash-meshed
|
||||
ownerReferences:
|
||||
- apiVersion: extensions/v1beta1
|
||||
kind: Deployment
|
||||
name: meshed-deployment
|
||||
status:
|
||||
phase: Running
|
||||
podIP: 1.2.3.4
|
||||
`,
|
||||
},
|
||||
req: &pb.ListPodsRequest{
|
||||
Selector: &pb.ResourceSelection{
|
||||
Resource: &pb.Resource{
|
||||
Type: pkgK8s.Pod,
|
||||
Name: "non-existing-pod",
|
||||
},
|
||||
},
|
||||
},
|
||||
res: &pb.ListPodsResponse{},
|
||||
},
|
||||
// matching owner type -> pod is part of the result
|
||||
listPodsExpected{
|
||||
err: nil,
|
||||
promRes: model.Vector{
|
||||
&model.Sample{
|
||||
Metric: model.Metric{"pod": "emojivoto-meshed"},
|
||||
Timestamp: 456,
|
||||
},
|
||||
},
|
||||
k8sRes: []string{`
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: emojivoto-meshed
|
||||
namespace: emojivoto
|
||||
labels:
|
||||
pod-template-hash: hash-meshed
|
||||
ownerReferences:
|
||||
- apiVersion: extensions/v1beta1
|
||||
kind: Deployment
|
||||
name: meshed-deployment
|
||||
status:
|
||||
phase: Running
|
||||
podIP: 1.2.3.4
|
||||
`,
|
||||
},
|
||||
req: &pb.ListPodsRequest{
|
||||
Selector: &pb.ResourceSelection{
|
||||
Resource: &pb.Resource{
|
||||
Type: pkgK8s.Deployment,
|
||||
Name: "meshed-deployment",
|
||||
},
|
||||
},
|
||||
},
|
||||
res: &pb.ListPodsResponse{
|
||||
Pods: []*pb.Pod{
|
||||
&pb.Pod{
|
||||
Name: "emojivoto/emojivoto-meshed",
|
||||
Added: true,
|
||||
SinceLastReport: &duration.Duration{},
|
||||
Status: "Running",
|
||||
PodIP: "1.2.3.4",
|
||||
Owner: &pb.Pod_Deployment{Deployment: "emojivoto/meshed-deployment"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
// matching label in request -> pod is in the response
|
||||
listPodsExpected{
|
||||
err: nil,
|
||||
promRes: model.Vector{
|
||||
&model.Sample{
|
||||
Metric: model.Metric{"pod": "emojivoto-meshed"},
|
||||
Timestamp: 456,
|
||||
},
|
||||
},
|
||||
k8sRes: []string{`
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: emojivoto-meshed
|
||||
namespace: emojivoto
|
||||
labels:
|
||||
pod-template-hash: hash-meshed
|
||||
ownerReferences:
|
||||
- apiVersion: extensions/v1beta1
|
||||
kind: Deployment
|
||||
name: meshed-deployment
|
||||
status:
|
||||
phase: Running
|
||||
podIP: 1.2.3.4
|
||||
`,
|
||||
},
|
||||
req: &pb.ListPodsRequest{
|
||||
Selector: &pb.ResourceSelection{
|
||||
LabelSelector: "pod-template-hash=hash-meshed",
|
||||
},
|
||||
},
|
||||
res: &pb.ListPodsResponse{
|
||||
Pods: []*pb.Pod{
|
||||
&pb.Pod{
|
||||
Name: "emojivoto/emojivoto-meshed",
|
||||
Added: true,
|
||||
SinceLastReport: &duration.Duration{},
|
||||
Status: "Running",
|
||||
PodIP: "1.2.3.4",
|
||||
Owner: &pb.Pod_Deployment{Deployment: "emojivoto/meshed-deployment"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
// NOT matching label in request -> pod is NOT in the response
|
||||
listPodsExpected{
|
||||
err: nil,
|
||||
promRes: model.Vector{
|
||||
&model.Sample{
|
||||
Metric: model.Metric{"pod": "emojivoto-meshed"},
|
||||
Timestamp: 456,
|
||||
},
|
||||
},
|
||||
k8sRes: []string{`
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: emojivoto-meshed
|
||||
namespace: emojivoto
|
||||
labels:
|
||||
pod-template-hash: hash-meshed
|
||||
ownerReferences:
|
||||
- apiVersion: extensions/v1beta1
|
||||
kind: Deployment
|
||||
name: meshed-deployment
|
||||
status:
|
||||
phase: Running
|
||||
podIP: 1.2.3.4
|
||||
`,
|
||||
},
|
||||
req: &pb.ListPodsRequest{
|
||||
Selector: &pb.ResourceSelection{
|
||||
LabelSelector: "non-existent-label=value",
|
||||
},
|
||||
},
|
||||
res: &pb.ListPodsResponse{},
|
||||
},
|
||||
}
|
||||
|
||||
for _, exp := range expectations {
|
||||
|
|
Loading…
Reference in New Issue