gitops-engine
gitops-engine copied to clipboard
Required permissions are too broad and not configurable
Currently gitops engine gets the list of api resources and starts watches for all of them that support list+watch verbs. This means a program, using the gitops engine, needs permissions for all of the above, which is not desirable most of the time because the user only needs to manage only a subset of resource types, not everything.
For example:
time="2020-07-20T05:32:12Z" level=error msg="Failed to sync cluster https://10.96.0.1:443: failed to load initial state of resource EndpointSlice.discovery.k8s.io: endpointslices.discovery.k8s.io is forbidden: User \"system:serviceaccount:agentk:agentk\" cannot list resource \"endpointslices\" in API group \"discovery.k8s.io\" at the cluster scope"
time="2020-07-20T05:32:35Z" level=warning msg="engine.Run() failed" error="failed to load initial state of resource LimitRange: limitranges is forbidden: User \"system:serviceaccount:agentk:agentk\" cannot list resource \"limitranges\" in API group \"\" at the cluster scope" project_id=root/gitops-manifests
time="2020-07-20T05:31:52Z" level=warning msg="engine.Run() failed" error="failed to load initial state of resource ResourceQuota: resourcequotas is forbidden: User \"system:serviceaccount:agentk:agentk\" cannot list resource \"resourcequotas\" in API group \"\" at the cluster scope" project_id=root/gitops-manifests
time="2020-07-20T05:31:12Z" level=warning msg="engine.Run() failed" error="failed to load initial state of resource Event.events.k8s.io: events.events.k8s.io is forbidden: User \"system:serviceaccount:agentk:agentk\" cannot list resource \"events\" in API group \"events.k8s.io\" at the cluster scope" project_id=root/gitops-manifests
I think a better way would be to only start watching resources of the types, passed to Sync() method of the engine. I.e. dynamically add and remove watches depending on what has been passed.
The engine already has the ability to configure which resources types should be watched. It should be possible to implement that you've described.
type myResourcesFilter struct {
}
func (f *myResourcesFilter) IsExcludedResource(group, kind, cluster string) bool {
return group == "apps" && kind == "Deployment" # more complex logic here which exclude all resources except types passed to Sync method.
}
clusterCache := cache.NewClusterCache(
config,
cache.SetSettings(cache.Settings{ResourcesFilter: &myResourcesFilter{}},
)
I agree this might be very popular use case and it is good to provide it as part of the library. The pkg/engine package is supposed to provide a convenient API engine and looks like a good candidate for this logic.
Nice! I saw the filtering but didn't pay close enough attention to it. I think it might be worth providing a filter that excludes things 99% of people will not want to manage like events, endpoint slices, etc.
It should be possible to implement that you've described.
Yes, but it would require recreating the cache and the engine (i.e. re-establishing all the watches) each time the resource list changes. It's probably fine and that's probably what I'm going to do but it's not perfect :) Anyway, thanks for a very helpful suggestion!
Feel free to close this issue or keep it open if you want to track the work of adding a common exclusion filter. I'm not going to contribute it anytime soon as I'm a bit too busy atm.