Skip to content

Commit 1ccca6c

Browse files
feat: node k8s permissions (#6123)
* node check removed * node rbac changes * bean dir * node * bean * wire gen * node operations rbac * node rbac * comment * catalog * get namespace rbac changes * k8s terminal session * or check * node
1 parent 344e877 commit 1ccca6c

File tree

11 files changed

+296
-52
lines changed

11 files changed

+296
-52
lines changed

api/cluster/ClusterRestHandler.go

Lines changed: 55 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import (
2525
"github.com/devtron-labs/devtron/pkg/cluster/rbac"
2626
"net/http"
2727
"strconv"
28+
"strings"
2829
"time"
2930

3031
"github.com/devtron-labs/devtron/pkg/auth/authorisation/casbin"
@@ -377,7 +378,7 @@ func (impl ClusterRestHandlerImpl) FindNoteByClusterId(w http.ResponseWriter, r
377378
}
378379
// RBAC enforcer applying
379380
token := r.Header.Get("token")
380-
authenticated, err := impl.clusterRbacService.CheckAuthorization(bean.ClusterName, bean.ClusterId, token, userId, false)
381+
authenticated, err := impl.clusterRbacService.CheckAuthorization(bean.ClusterName, bean.ClusterId, token, userId, true)
381382
if err != nil {
382383
impl.logger.Errorw("error in checking rbac for cluster", "err", err, "clusterId", bean.ClusterId)
383384
common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
@@ -477,7 +478,8 @@ func (impl ClusterRestHandlerImpl) UpdateClusterDescription(w http.ResponseWrite
477478
return
478479
}
479480
// RBAC enforcer applying
480-
if ok := impl.enforcer.Enforce(token, casbin.ResourceCluster, casbin.ActionUpdate, clusterDescription.ClusterName); !ok {
481+
authenticated := impl.clusterRbacService.CheckAuthorisationForAllK8sPermissions(token, clusterDescription.ClusterName, casbin.ActionUpdate)
482+
if !authenticated {
481483
common.WriteJsonResp(w, errors.New("unauthorized"), nil, http.StatusForbidden)
482484
return
483485
}
@@ -521,7 +523,8 @@ func (impl ClusterRestHandlerImpl) UpdateClusterNote(w http.ResponseWriter, r *h
521523
return
522524
}
523525
// RBAC enforcer applying
524-
if ok := impl.enforcer.Enforce(token, casbin.ResourceCluster, casbin.ActionUpdate, clusterDescription.ClusterName); !ok {
526+
authenticated := impl.clusterRbacService.CheckAuthorisationForAllK8sPermissions(token, clusterDescription.ClusterName, casbin.ActionUpdate)
527+
if !authenticated {
525528
common.WriteJsonResp(w, errors.New("unauthorized"), nil, http.StatusForbidden)
526529
return
527530
}
@@ -622,17 +625,61 @@ func (impl ClusterRestHandlerImpl) DeleteCluster(w http.ResponseWriter, r *http.
622625

623626
func (impl ClusterRestHandlerImpl) GetAllClusterNamespaces(w http.ResponseWriter, r *http.Request) {
624627
token := r.Header.Get("token")
628+
userId, err := impl.userService.GetLoggedInUser(r)
629+
if userId == 0 || err != nil {
630+
impl.logger.Errorw("err, GetAllClusterNamespaces", "error", err, "userId", userId)
631+
common.WriteJsonResp(w, err, "Unauthorized User", http.StatusUnauthorized)
632+
return
633+
}
625634
clusterNamespaces := impl.clusterService.GetAllClusterNamespaces()
626635

627636
// RBAC enforcer applying
628-
for clusterName, _ := range clusterNamespaces {
629-
if ok := impl.enforcer.Enforce(token, casbin.ResourceCluster, casbin.ActionGet, clusterName); !ok {
630-
delete(clusterNamespaces, clusterName)
631-
}
637+
filteredClusterNamespaces, err := impl.HandleRbacForClusterNamespace(userId, token, clusterNamespaces)
638+
if err != nil {
639+
impl.logger.Errorw("error in GetAllClusterNamespaces", "err", err)
640+
common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
641+
return
632642
}
633643
//RBAC enforcer Ends
634644

635-
common.WriteJsonResp(w, nil, clusterNamespaces, http.StatusOK)
645+
common.WriteJsonResp(w, nil, filteredClusterNamespaces, http.StatusOK)
646+
}
647+
648+
func (impl ClusterRestHandlerImpl) HandleRbacForClusterNamespace(userId int32, token string, clusterNamespaces map[string][]string) (map[string][]string, error) {
649+
filteredClusterNamespaces := make(map[string][]string)
650+
if ok := impl.enforcer.Enforce(token, casbin.ResourceGlobal, casbin.ActionGet, "*"); ok {
651+
return clusterNamespaces, nil
652+
}
653+
roles, err := impl.clusterService.FetchRolesFromGroup(userId)
654+
if err != nil {
655+
impl.logger.Errorw("error on fetching user roles for cluster list", "err", err)
656+
return nil, err
657+
}
658+
659+
clusterAndNameSpaceVsAllowedMap := make(map[string]bool, len(roles))
660+
clusterNameVsAllAllowedMap := make(map[string]bool, len(roles))
661+
for _, role := range roles {
662+
clusterAndNameSpaceVsAllowedMap[strings.ToLower(role.Cluster+"_"+role.Namespace)] = true
663+
if role.Namespace == "" {
664+
clusterNameVsAllAllowedMap[role.Cluster] = true
665+
} else {
666+
clusterNameVsAllAllowedMap[role.Cluster] = false
667+
}
668+
}
669+
670+
for clusterName, allNamespaces := range clusterNamespaces {
671+
if val, exist := clusterNameVsAllAllowedMap[clusterName]; val {
672+
filteredClusterNamespaces[clusterName] = allNamespaces
673+
} else if exist {
674+
for _, namespace := range allNamespaces {
675+
if val2, exist2 := clusterAndNameSpaceVsAllowedMap[strings.ToLower(clusterName+"_"+namespace)]; exist2 && val2 {
676+
filteredClusterNamespaces[clusterName] = append(filteredClusterNamespaces[clusterName], namespace)
677+
}
678+
}
679+
}
680+
}
681+
return filteredClusterNamespaces, nil
682+
636683
}
637684

638685
func (impl ClusterRestHandlerImpl) GetClusterNamespaces(w http.ResponseWriter, r *http.Request) {

api/k8s/application/k8sApplicationRestHandler.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -816,7 +816,8 @@ func (handler *K8sApplicationRestHandlerImpl) GetTerminalSession(w http.Response
816816

817817
} else if resourceRequestBean.AppIdentifier == nil && resourceRequestBean.DevtronAppIdentifier == nil && resourceRequestBean.ExternalFluxAppIdentifier == nil && resourceRequestBean.ExternalArgoApplicationName == "" && resourceRequestBean.ClusterId > 0 {
818818
//RBAC enforcer applying for Resource Browser
819-
if !handler.handleRbac(r, w, *resourceRequestBean, token, casbin.ActionUpdate) {
819+
resource, object := handler.enforcerUtil.GetRbacResourceAndObjectForNodeByClusterId(resourceRequestBean.ClusterId, bean2.ALL)
820+
if !(handler.enforcer.Enforce(token, resource, casbin.ActionUpdate, object) || handler.handleRbac(r, w, *resourceRequestBean, token, casbin.ActionUpdate)) {
820821
return
821822
}
822823
//RBAC enforcer Ends

api/k8s/capacity/k8sCapacityRestHandler.go

Lines changed: 38 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ func (handler *K8sCapacityRestHandlerImpl) GetClusterDetail(w http.ResponseWrite
179179
common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
180180
return
181181
}
182-
authenticated, err := handler.clusterRbacService.CheckAuthorization(cluster.ClusterName, cluster.Id, token, userId, false)
182+
authenticated, err := handler.clusterRbacService.CheckAuthorization(cluster.ClusterName, cluster.Id, token, userId, true)
183183
if err != nil {
184184
handler.logger.Errorw("error in checking rbac for cluster", "err", err, "clusterId", clusterId)
185185
common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
@@ -219,12 +219,7 @@ func (handler *K8sCapacityRestHandlerImpl) GetNodeList(w http.ResponseWriter, r
219219
common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
220220
return
221221
}
222-
authenticated, err := handler.clusterRbacService.CheckAuthorization(cluster.ClusterName, cluster.Id, token, userId, false)
223-
if err != nil {
224-
handler.logger.Errorw("error in checking rbac for cluster", "err", err, "clusterId", clusterId)
225-
common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
226-
return
227-
}
222+
authenticated := handler.clusterRbacService.CheckAuthorisationForNode(token, cluster.ClusterName, "", casbin.ActionGet)
228223
if !authenticated {
229224
common.WriteJsonResp(w, errors.New("unauthorized"), nil, http.StatusForbidden)
230225
return
@@ -265,12 +260,7 @@ func (handler *K8sCapacityRestHandlerImpl) GetNodeDetail(w http.ResponseWriter,
265260
common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
266261
return
267262
}
268-
authenticated, err := handler.clusterRbacService.CheckAuthorization(cluster.ClusterName, cluster.Id, token, userId, false)
269-
if err != nil {
270-
handler.logger.Errorw("error in checking rbac for cluster", "err", err, "clusterId", clusterId)
271-
common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
272-
return
273-
}
263+
authenticated := handler.clusterRbacService.CheckAuthorisationForNode(token, cluster.ClusterName, name, casbin.ActionGet)
274264
if !authenticated {
275265
common.WriteJsonResp(w, errors.New("unauthorized"), nil, http.StatusForbidden)
276266
return
@@ -300,7 +290,13 @@ func (handler *K8sCapacityRestHandlerImpl) UpdateNodeManifest(w http.ResponseWri
300290
}
301291
// RBAC enforcer applying
302292
token := r.Header.Get("token")
303-
if ok := handler.enforcer.Enforce(token, casbin.ResourceGlobal, casbin.ActionUpdate, "*"); !ok {
293+
authenticated, err := handler.clusterRbacService.CheckAuthorisationForNodeWithClusterId(token, manifestUpdateReq.ClusterId, manifestUpdateReq.Name, casbin.ActionUpdate)
294+
if err != nil {
295+
handler.logger.Errorw("error in checking rbac for cluster", "err", err, "clusterId", manifestUpdateReq.ClusterId)
296+
common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
297+
return
298+
}
299+
if !authenticated {
304300
common.WriteJsonResp(w, errors.New("unauthorized"), nil, http.StatusForbidden)
305301
return
306302
}
@@ -329,7 +325,13 @@ func (handler *K8sCapacityRestHandlerImpl) DeleteNode(w http.ResponseWriter, r *
329325
}
330326
// RBAC enforcer applying
331327
token := r.Header.Get("token")
332-
if ok := handler.enforcer.Enforce(token, casbin.ResourceGlobal, casbin.ActionDelete, "*"); !ok {
328+
authenticated, err := handler.clusterRbacService.CheckAuthorisationForNodeWithClusterId(token, nodeDelReq.ClusterId, nodeDelReq.Name, casbin.ActionDelete)
329+
if err != nil {
330+
handler.logger.Errorw("error in checking rbac for cluster", "err", err, "clusterId", nodeDelReq.ClusterId)
331+
common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
332+
return
333+
}
334+
if !authenticated {
333335
common.WriteJsonResp(w, errors.New("unauthorized"), nil, http.StatusForbidden)
334336
return
335337
}
@@ -367,7 +369,13 @@ func (handler *K8sCapacityRestHandlerImpl) CordonOrUnCordonNode(w http.ResponseW
367369
}
368370
// RBAC enforcer applying
369371
token := r.Header.Get("token")
370-
if ok := handler.enforcer.Enforce(token, casbin.ResourceGlobal, casbin.ActionUpdate, "*"); !ok {
372+
authenticated, err := handler.clusterRbacService.CheckAuthorisationForNodeWithClusterId(token, nodeCordonReq.ClusterId, nodeCordonReq.Name, casbin.ActionUpdate)
373+
if err != nil {
374+
handler.logger.Errorw("error in checking rbac for cluster", "err", err, "clusterId", nodeCordonReq.ClusterId)
375+
common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
376+
return
377+
}
378+
if !authenticated {
371379
common.WriteJsonResp(w, errors.New("unauthorized"), nil, http.StatusForbidden)
372380
return
373381
}
@@ -396,7 +404,13 @@ func (handler *K8sCapacityRestHandlerImpl) DrainNode(w http.ResponseWriter, r *h
396404
}
397405
// RBAC enforcer applying
398406
token := r.Header.Get("token")
399-
if ok := handler.enforcer.Enforce(token, casbin.ResourceGlobal, casbin.ActionUpdate, "*"); !ok {
407+
authenticated, err := handler.clusterRbacService.CheckAuthorisationForNodeWithClusterId(token, nodeDrainReq.ClusterId, nodeDrainReq.Name, casbin.ActionUpdate)
408+
if err != nil {
409+
handler.logger.Errorw("error in checking rbac for cluster", "err", err, "clusterId", nodeDrainReq.ClusterId)
410+
common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
411+
return
412+
}
413+
if !authenticated {
400414
common.WriteJsonResp(w, errors.New("unauthorized"), nil, http.StatusForbidden)
401415
return
402416
}
@@ -425,7 +439,13 @@ func (handler *K8sCapacityRestHandlerImpl) EditNodeTaints(w http.ResponseWriter,
425439
}
426440
// RBAC enforcer applying
427441
token := r.Header.Get("token")
428-
if ok := handler.enforcer.Enforce(token, casbin.ResourceGlobal, casbin.ActionUpdate, "*"); !ok {
442+
authenticated, err := handler.clusterRbacService.CheckAuthorisationForNodeWithClusterId(token, nodeTaintReq.ClusterId, nodeTaintReq.Name, casbin.ActionUpdate)
443+
if err != nil {
444+
handler.logger.Errorw("error in checking rbac for cluster", "err", err, "clusterId", nodeTaintReq.ClusterId)
445+
common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
446+
return
447+
}
448+
if !authenticated {
429449
common.WriteJsonResp(w, errors.New("unauthorized"), nil, http.StatusForbidden)
430450
return
431451
}

0 commit comments

Comments
 (0)