Most default pipeline entries use singular resource names, so those informers never sync
Nobody has claimed this yet.
- Dominant language
- Go
- Stars
- 90
- Forks
- 96
- PR merge metrics
- No merged PRs in 30d
Description
**Description**
Most of the resource entries in `internal/config/default_config.go` use the singular Kubernetes kind name where the API expects the plural resource name. Kubernetes API paths are keyed by the plural resource, so those informers watch a path that does not exist and never sync anything. The affected resources are silently absent from MeshSync data.
43 of the 71 entries in `Pipelines` have a singular first segment. The first block (namespaces, configmaps, nodes, secrets, pods, services, deployments, replicasets, statefulsets, daemonsets, ingresses, endpoints, endpointslices, persistentvolumes, persistentvolumeclaims) is correctly plural, and so is every entry in the local whitelist in `internal/config/config_local.go` (`cronjobs.v1.batch`, `storageclasses.v1.storage.k8s.io`, `clusterroles.v1.rbac.authorization.k8s.io`, `volumeattachments.v1.storage.k8s.io`, `apiservices.v1.apiregistration.k8s.io`). The later block in `default_config.go` is the one that diverges.
The clearest single piece of evidence is that `nodes.v1.` and `node.v1.` are both registered, at `default_config.go:31` and `default_config.go:261`. Only the first can work.
**Why the singular names cannot work**
`internal/pipeline/step.go:46` parses the entry and hands the result straight to the dynamic informer, with no RESTMapper and no discovery lookup:
```go
gvr, _ := schema.ParseResourceArg(ri.config.Name)
if gvr == nil { ... }
iclient := ri.informer.ForResource(*gvr)
```
`schema.ParseResourceArg` only splits the string, so whatever is written becomes the resource segment of the URL verbatim. Running it over a sample of the current entries:
```
pods.v1. -> Resource="pods" Version="v1" Group=""
nodes.v1. -> Resource="nodes" Version="v1" Group=""
node.v1. -> Resource="node" Version="v1" Group=""
job.v1.batch -> Resource="job" Version="v1" Group="batch"
event.v1.events.k8s.io -> Resource="event" Version="v1" Group="events.k8s.io"
resourcequota.v1. -> Resource="resourcequota" Version="v1" Group=""
```
So the `job.v1.batch` informer lists and watches `/apis/batch/v1/job` instead of `/apis/batch/v1/jobs`. Since nothing validates the GVR against server discovery, this fails at list/watch time rather than at startup.
**Expected Behavior**
Every configured resource is actually watched, or an unusable entry is reported at startup instead of failing quietly.
**Impact**
Resources that users would reasonably expect MeshSync to discover are missing, including Jobs, Events, ServiceAccounts, Roles, RoleBindings, ClusterRoleBindings, NetworkPolicies, ResourceQuotas, LimitRanges, Leases, HorizontalPodAutoscalers, PodDisruptionBudgets, CustomResourceDefinitions, ControllerRevisions, the CSI resources, and the webhook configurations.
This also explains why Kubernetes Events are absent from MeshSync data today. Worth noting separately: even with the resource name corrected to `events.v1.events.k8s.io`, `ParseList` in `pkg/model/model_converter.go` keeps only the generic object fields, so `reason`, `message` / `note`, `regarding` and `count` would still be dropped. Events need a follow-up beyond the rename to be useful.
**Suggested fix**
The entries fall into four groups, and they want different treatment:
1. Real listable resources written in the singular. Pluralize: `job.v1.batch` -> `jobs.v1.batch`, `event.v1.events.k8s.io` -> `events.v1.events.k8s.io`, `resourcequota.v1.` -> `resourcequotas.v1.`, `serviceaccount.v1.` -> `serviceaccounts.v1.`, `networkpolicy.v1.networking.k8s.io` -> `networkpolicies...`, `csistoragecapacity...` -> `csistoragecapacities...`, and so on for the rest of the group.
2. Non-listable, create-only endpoints that no informer can watch: `tokenreview`, `tokenrequest`, `subjectaccessreview`, `selfsubjectaccessreview`, `selfsubjectrulesreview`, `selfsubjectreview`, `localsubjectaccessreview`, `binding`. These should be removed rather than renamed.
3. Entries that are not Kubernetes API resources at all: `container.v1.core`, `service.apis`, `volume.v1.`.
4. The duplicate `node.v1.` at line 261, superseded by `nodes.v1.` at line 31.
A guard alongside the data fix would stop this class of problem recurring: resolve each configured entry through discovery or a RESTMapper at startup and log the ones the cluster does not recognise, instead of registering an informer that can never list.
I am happy to send a PR for the renames and removals, and separately for the startup validation, if that split works for you. Wanted to confirm the intended disposition of groups 2 and 3 first, since removing entries changes what a cluster is configured to watch.
**Environment:**
- Version: `internal/config/default_config.go` on master (verified at commit 91420b0)
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the affected entries in internal/config/default_config.go and compare them with internal/config/config_local.go. Read internal/pipeline/step.go:46 to confirm how resource names become informer paths, then review pkg/model/model_converter.go for the separate Events concern. Done means each configured entry is either a valid watched resource or an explicitly removed or reported unusable entry, with the group 2 and 3 dispositions confirmed.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go, kubernetes
- Domain
- backend-api-design, infrastructure
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 50/100