metalbear-co / mirrord

Connect your local process and your cloud environment, and run local code in cloud conditions.
https://mirrord.dev
MIT License
3.75k stars 101 forks source link

`matchExpressions` ignored on pod selection #2770

Open t4lz opened 1 week ago

t4lz commented 1 week ago

When targeting target types that have multiple pods, we select a pod using the target object's label selector, however, it seems we are currently ignoring the matchExpressions field of the label selector, and only take the matchLabels field.

Impact

Those two fields are ANDed, so if a user defines a condition using both matchLabels and matchExpressions, we would ignore the restriction defined by the matchExpressions on selected pods, and in the worse case scenario we would select a pod from a different deployment/rollout/...

Also, we return an error if there are no matchLabels, but I think that's a valid case - when the label selector is defined based on match expressions alone.

Example for one of the places we only use selector.match_labels:

https://github.com/metalbear-co/mirrord/blob/7b8dae671f4cc2d70864100c1cc4d10659368bf6/mirrord/kube/src/api/runtime/deployment.rs#L20-L26

Reproduction

no-expressions.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: no-exps
  labels:
    app: py-serv
spec:
  replicas: 1
  selector:
    matchLabels:
      app: py-serv
  template:
    metadata:
      labels:
        app: py-serv
    spec:
      containers:
        - name: py-serv
          image: ghcr.io/metalbear-co/mirrord-pytest:latest

has-expressions.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: has-exps
  labels:
    app: py-serv
spec:
  replicas: 1
  selector:
    matchLabels:
      app: py-serv
    matchExpressions:
      - { key: gotcha, operator: Exists }
  template:
    metadata:
      labels:
        app: py-serv
        gotcha: haha
    spec:
      containers:
        - name: py-serv
          image: ghcr.io/metalbear-co/mirrord-pytest:latest

If you define those two deployments, and run mirrord with the operator, targeting deploy/has-exps, agents will be created for both pods.

If you run without the operator, targeting deploy/has-exps, you might target the pod from the wrong deployment:

MIRRORD_PROGRESS_MODE=off MIRRORD_OPERATOR_ENABLED=false mirrord exec -t deploy/has-exps hostname
no-exps-7cdc865574-mpxtx
linear[bot] commented 1 week ago

MBE-401 `matchExpression`s ignored on pod selection