Skip to content

CLI --label-selector unexpectedly mutates local config (fill) and causes overwrites of all resources with that label #373

Description

@juzhiyuan

Current Behavior

When running adc sync with --label-selector, the CLI merges the selector into labels of ALL local resources (including nested routes/stream_routes) instead of only selecting resources to sync. Combined with remote-side filtering, this leads to overwriting all resources on the remote that carry the selector label.

This behaviour contradicts the help text/semantics of “Synchronize only the resources with the specified labels”.

Actual Behaviour

  • Local: the selector is merged into labels of all resources (including nested resources).
  • Remote: fetch/dump is filtered by the selector.
  • Diff+Sync: the “selector-filled” local config overwrites all remote resources that have the selector.

This behaviour can surprise users in multi-team or shared gateways where label-based scoping is expected to narrow sync impact.

Impact

  • Unintended propagation of the selector label to unrelated local resources during the operation.
  • Overwrites to all remote resources carrying the label, which is risky in shared environments.

Expected Behavior

--label-selector should limit what gets synchronized (i.e., filter), not mutate local resources by adding those labels.

Steps to Reproduce

  1. Seed remote (two routes, no route-id label):
services:
  - name: app-main
    labels:
      app: app-main
    upstream:
      type: roundrobin
      nodes:
        - host: 127.0.0.1
          port: 8080
          weight: 1
    routes:
      - name: r-a
        labels:
          app: app-main
        uris: ["/a"]
        methods: ["GET"]
      - name: r-b
        labels:
          app: app-main
        uris: ["/b"]
        methods: ["GET"]

Sync it:

adc sync -f seed.yaml \
  --backend api7 \
  --server http://SERVER \
  --token TOKEN \
  --include-resource-type service \
  --include-resource-type route
  1. Locally only add a second label to route r-a:
services:
  - name: app-main
    labels:
      app: app-main
    upstream:
      type: roundrobin
      nodes:
        - host: 127.0.0.1
          port: 8080
          weight: 1
    routes:
      - name: r-a
        labels:
          app: app-main
          route-id: batch-requests   # only this route has the new label
        uris: ["/a"]
        methods: ["GET"]
      - name: r-b
        labels:
          app: app-main              # unchanged, no route-id
        uris: ["/b"]
        methods: ["GET"]

Run sync with selector:

adc sync -f update.yaml \
  --backend api7 \
  --server http://SERVER \
  --token TOKEN \
  --label-selector route-id=batch-requests

Observe:

adc dump \
  --backend api7 \
  --server http://SERVER \
  --token TOKEN \
  --label-selector route-id=batch-requests

Expected only r-a to be affected, but r-b and the parent service app-main also end up being overwritten with route-id: batch-requests.

Additional Behaviour

After sync again, the Service and r-b also labeled with route-id=batch-requests.

Image

Environment

  • adc version: 0.21.2
  • backend: both api7 and apisix

Metadata

Metadata

Assignees

Labels

questionFurther information is requested

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions