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) {
|
func (s *grpcServer) ListPods(ctx context.Context, req *pb.ListPodsRequest) (*pb.ListPodsResponse, error) {
|
||||||
log.Debugf("ListPods request: %+v", req)
|
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
|
// Reports is a map from instance name to the absolute time of the most recent
|
||||||
// report from that instance and its process start time
|
// report from that instance and its process start time
|
||||||
reports := make(map[string]podReport)
|
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")
|
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 := ""
|
nsQuery := ""
|
||||||
namespace := ""
|
namespace := ""
|
||||||
if req.GetNamespace() != "" {
|
if req.GetNamespace() != "" {
|
||||||
namespace = req.GetNamespace()
|
namespace = req.GetNamespace()
|
||||||
} else if req.GetSelector().GetResource().GetNamespace() != "" {
|
} else if targetOwner.GetNamespace() != "" {
|
||||||
namespace = req.GetSelector().GetResource().GetNamespace()
|
namespace = targetOwner.GetNamespace()
|
||||||
} else if req.GetSelector().GetResource().GetType() == pkgK8s.Namespace {
|
} else if targetOwner.GetType() == pkgK8s.Namespace {
|
||||||
namespace = req.GetSelector().GetResource().GetName()
|
namespace = targetOwner.GetName()
|
||||||
}
|
}
|
||||||
if namespace != "" {
|
if namespace != "" {
|
||||||
nsQuery = fmt.Sprintf("namespace=\"%s\"", 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
|
var pods []*k8sV1.Pod
|
||||||
if namespace != "" {
|
if namespace != "" {
|
||||||
pods, err = s.k8sAPI.Pod().Lister().Pods(namespace).List(labels.Everything())
|
pods, err = s.k8sAPI.Pod().Lister().Pods(namespace).List(labelSelector)
|
||||||
} else {
|
} else {
|
||||||
pods, err = s.k8sAPI.Pod().Lister().List(labels.Everything())
|
pods, err = s.k8sAPI.Pod().Lister().List(labelSelector)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -126,6 +137,18 @@ func (s *grpcServer) ListPods(ctx context.Context, req *pb.ListPodsRequest) (*pb
|
||||||
continue
|
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]
|
updated, added := reports[pod.Name]
|
||||||
|
|
||||||
status := string(pod.Status.Phase)
|
status := string(pod.Status.Phase)
|
||||||
|
@ -162,7 +185,6 @@ func (s *grpcServer) ListPods(ctx context.Context, req *pb.ListPodsRequest) (*pb
|
||||||
ProxyVersion: proxyVersion,
|
ProxyVersion: proxyVersion,
|
||||||
}
|
}
|
||||||
|
|
||||||
ownerKind, ownerName := s.k8sAPI.GetOwnerKindAndName(pod)
|
|
||||||
namespacedOwnerName := pod.Namespace + "/" + ownerName
|
namespacedOwnerName := pod.Namespace + "/" + ownerName
|
||||||
|
|
||||||
switch ownerKind {
|
switch ownerKind {
|
||||||
|
|
|
@ -227,6 +227,166 @@ spec:
|
||||||
res: &pb.ListPodsResponse{},
|
res: &pb.ListPodsResponse{},
|
||||||
promReqNamespace: "testnamespace",
|
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 {
|
for _, exp := range expectations {
|
||||||
|
|
Loading…
Reference in New Issue