mirror of
https://github.com/portainer/portainer.git
synced 2025-07-31 03:09:44 +02:00
fix(kubernetes): Namespace access permission changes role bindings not created [R8S-366] (#807)
Co-authored-by: andres-portainer <andres-portainer@users.noreply.github.com> Co-authored-by: Malcolm Lockyer <segfault88@users.noreply.github.com>
This commit is contained in:
parent
ee6d33365e
commit
7fd5b96130
2 changed files with 17 additions and 9 deletions
|
@ -75,7 +75,7 @@ func (handler *Handler) listRegistries(tx dataservices.DataStoreTx, r *http.Requ
|
||||||
return nil, httperror.InternalServerError("Unable to retrieve registries from the database", err)
|
return nil, httperror.InternalServerError("Unable to retrieve registries from the database", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
registries, handleError := handler.filterRegistriesByAccess(r, registries, endpoint, user, securityContext.UserMemberships)
|
registries, handleError := handler.filterRegistriesByAccess(tx, r, registries, endpoint, user, securityContext.UserMemberships)
|
||||||
if handleError != nil {
|
if handleError != nil {
|
||||||
return nil, handleError
|
return nil, handleError
|
||||||
}
|
}
|
||||||
|
@ -87,15 +87,15 @@ func (handler *Handler) listRegistries(tx dataservices.DataStoreTx, r *http.Requ
|
||||||
return registries, err
|
return registries, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (handler *Handler) filterRegistriesByAccess(r *http.Request, registries []portainer.Registry, endpoint *portainer.Endpoint, user *portainer.User, memberships []portainer.TeamMembership) ([]portainer.Registry, *httperror.HandlerError) {
|
func (handler *Handler) filterRegistriesByAccess(tx dataservices.DataStoreTx, r *http.Request, registries []portainer.Registry, endpoint *portainer.Endpoint, user *portainer.User, memberships []portainer.TeamMembership) ([]portainer.Registry, *httperror.HandlerError) {
|
||||||
if !endpointutils.IsKubernetesEndpoint(endpoint) {
|
if !endpointutils.IsKubernetesEndpoint(endpoint) {
|
||||||
return security.FilterRegistries(registries, user, memberships, endpoint.ID), nil
|
return security.FilterRegistries(registries, user, memberships, endpoint.ID), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return handler.filterKubernetesEndpointRegistries(r, registries, endpoint, user, memberships)
|
return handler.filterKubernetesEndpointRegistries(tx, r, registries, endpoint, user, memberships)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (handler *Handler) filterKubernetesEndpointRegistries(r *http.Request, registries []portainer.Registry, endpoint *portainer.Endpoint, user *portainer.User, memberships []portainer.TeamMembership) ([]portainer.Registry, *httperror.HandlerError) {
|
func (handler *Handler) filterKubernetesEndpointRegistries(tx dataservices.DataStoreTx, r *http.Request, registries []portainer.Registry, endpoint *portainer.Endpoint, user *portainer.User, memberships []portainer.TeamMembership) ([]portainer.Registry, *httperror.HandlerError) {
|
||||||
namespaceParam, _ := request.RetrieveQueryParameter(r, "namespace", true)
|
namespaceParam, _ := request.RetrieveQueryParameter(r, "namespace", true)
|
||||||
isAdmin, err := security.IsAdmin(r)
|
isAdmin, err := security.IsAdmin(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -116,7 +116,7 @@ func (handler *Handler) filterKubernetesEndpointRegistries(r *http.Request, regi
|
||||||
return registries, nil
|
return registries, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return handler.filterKubernetesRegistriesByUserRole(r, registries, endpoint, user)
|
return handler.filterKubernetesRegistriesByUserRole(tx, r, registries, endpoint, user)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (handler *Handler) isNamespaceAuthorized(endpoint *portainer.Endpoint, namespace string, userId portainer.UserID, memberships []portainer.TeamMembership, isAdmin bool) (bool, error) {
|
func (handler *Handler) isNamespaceAuthorized(endpoint *portainer.Endpoint, namespace string, userId portainer.UserID, memberships []portainer.TeamMembership, isAdmin bool) (bool, error) {
|
||||||
|
@ -169,7 +169,7 @@ func registryAccessPoliciesContainsNamespace(registryAccess portainer.RegistryAc
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (handler *Handler) filterKubernetesRegistriesByUserRole(r *http.Request, registries []portainer.Registry, endpoint *portainer.Endpoint, user *portainer.User) ([]portainer.Registry, *httperror.HandlerError) {
|
func (handler *Handler) filterKubernetesRegistriesByUserRole(tx dataservices.DataStoreTx, r *http.Request, registries []portainer.Registry, endpoint *portainer.Endpoint, user *portainer.User) ([]portainer.Registry, *httperror.HandlerError) {
|
||||||
err := handler.requestBouncer.AuthorizedEndpointOperation(r, endpoint)
|
err := handler.requestBouncer.AuthorizedEndpointOperation(r, endpoint)
|
||||||
if errors.Is(err, security.ErrAuthorizationRequired) {
|
if errors.Is(err, security.ErrAuthorizationRequired) {
|
||||||
return nil, httperror.Forbidden("User is not authorized", err)
|
return nil, httperror.Forbidden("User is not authorized", err)
|
||||||
|
@ -178,7 +178,7 @@ func (handler *Handler) filterKubernetesRegistriesByUserRole(r *http.Request, re
|
||||||
return nil, httperror.InternalServerError("Unable to retrieve info from request context", err)
|
return nil, httperror.InternalServerError("Unable to retrieve info from request context", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
userNamespaces, err := handler.userNamespaces(endpoint, user)
|
userNamespaces, err := handler.userNamespaces(tx, endpoint, user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, httperror.InternalServerError("unable to retrieve user namespaces", err)
|
return nil, httperror.InternalServerError("unable to retrieve user namespaces", err)
|
||||||
}
|
}
|
||||||
|
@ -186,7 +186,7 @@ func (handler *Handler) filterKubernetesRegistriesByUserRole(r *http.Request, re
|
||||||
return filterRegistriesByNamespaces(registries, endpoint.ID, userNamespaces), nil
|
return filterRegistriesByNamespaces(registries, endpoint.ID, userNamespaces), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (handler *Handler) userNamespaces(endpoint *portainer.Endpoint, user *portainer.User) ([]string, error) {
|
func (handler *Handler) userNamespaces(tx dataservices.DataStoreTx, endpoint *portainer.Endpoint, user *portainer.User) ([]string, error) {
|
||||||
kcl, err := handler.K8sClientFactory.GetPrivilegedKubeClient(endpoint)
|
kcl, err := handler.K8sClientFactory.GetPrivilegedKubeClient(endpoint)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -197,7 +197,7 @@ func (handler *Handler) userNamespaces(endpoint *portainer.Endpoint, user *porta
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
userMemberships, err := handler.DataStore.TeamMembership().TeamMembershipsByUserID(user.ID)
|
userMemberships, err := tx.TeamMembership().TeamMembershipsByUserID(user.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,6 +87,14 @@ func (factory *ClientFactory) ClearClientCache() {
|
||||||
// Remove the cached kube client so a new one can be created
|
// Remove the cached kube client so a new one can be created
|
||||||
func (factory *ClientFactory) RemoveKubeClient(endpointID portainer.EndpointID) {
|
func (factory *ClientFactory) RemoveKubeClient(endpointID portainer.EndpointID) {
|
||||||
factory.endpointProxyClients.Delete(strconv.Itoa(int(endpointID)))
|
factory.endpointProxyClients.Delete(strconv.Itoa(int(endpointID)))
|
||||||
|
|
||||||
|
endpointPrefix := strconv.Itoa(int(endpointID)) + "."
|
||||||
|
|
||||||
|
for key := range factory.endpointProxyClients.Items() {
|
||||||
|
if strings.HasPrefix(key, endpointPrefix) {
|
||||||
|
factory.endpointProxyClients.Delete(key)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetPrivilegedKubeClient checks if an existing client is already registered for the environment(endpoint) and returns it if one is found.
|
// GetPrivilegedKubeClient checks if an existing client is already registered for the environment(endpoint) and returns it if one is found.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue