@@ -20,8 +20,12 @@ import (
20
20
"context"
21
21
"encoding/json"
22
22
"errors"
23
+ bean2 "github.com/devtron-labs/devtron/pkg/cluster/bean"
24
+ "github.com/devtron-labs/devtron/pkg/cluster/environment"
25
+ "github.com/devtron-labs/devtron/pkg/cluster/rbac"
23
26
"net/http"
24
27
"strconv"
28
+ "strings"
25
29
"time"
26
30
27
31
"github.com/devtron-labs/devtron/pkg/auth/authorisation/casbin"
@@ -69,8 +73,8 @@ type ClusterRestHandlerImpl struct {
69
73
enforcer casbin.Enforcer
70
74
deleteService delete2.DeleteService
71
75
argoUserService argo.ArgoUserService
72
- environmentService cluster .EnvironmentService
73
- clusterRbacService cluster .ClusterRbacService
76
+ environmentService environment .EnvironmentService
77
+ clusterRbacService rbac .ClusterRbacService
74
78
}
75
79
76
80
func NewClusterRestHandlerImpl (clusterService cluster.ClusterService ,
@@ -82,8 +86,8 @@ func NewClusterRestHandlerImpl(clusterService cluster.ClusterService,
82
86
enforcer casbin.Enforcer ,
83
87
deleteService delete2.DeleteService ,
84
88
argoUserService argo.ArgoUserService ,
85
- environmentService cluster .EnvironmentService ,
86
- clusterRbacService cluster .ClusterRbacService ) * ClusterRestHandlerImpl {
89
+ environmentService environment .EnvironmentService ,
90
+ clusterRbacService rbac .ClusterRbacService ) * ClusterRestHandlerImpl {
87
91
return & ClusterRestHandlerImpl {
88
92
clusterService : clusterService ,
89
93
clusterNoteService : clusterNoteService ,
@@ -107,7 +111,7 @@ func (impl ClusterRestHandlerImpl) SaveClusters(w http.ResponseWriter, r *http.R
107
111
common .WriteJsonResp (w , err , "Unauthorized User" , http .StatusUnauthorized )
108
112
return
109
113
}
110
- beans := []* cluster .ClusterBean {}
114
+ beans := []* bean2 .ClusterBean {}
111
115
err = decoder .Decode (& beans )
112
116
if err != nil {
113
117
impl .logger .Errorw ("request err, Save" , "error" , err , "payload" , beans )
@@ -178,7 +182,7 @@ func (impl ClusterRestHandlerImpl) Save(w http.ResponseWriter, r *http.Request)
178
182
common .WriteJsonResp (w , err , "Unauthorized User" , http .StatusUnauthorized )
179
183
return
180
184
}
181
- bean := new (cluster .ClusterBean )
185
+ bean := new (bean2 .ClusterBean )
182
186
err = decoder .Decode (bean )
183
187
if err != nil {
184
188
impl .logger .Errorw ("request err, Save" , "error" , err , "payload" , bean )
@@ -247,7 +251,7 @@ func (impl ClusterRestHandlerImpl) ValidateKubeconfig(w http.ResponseWriter, r *
247
251
common .WriteJsonResp (w , err , "Unauthorized User" , http .StatusUnauthorized )
248
252
return
249
253
}
250
- bean := & cluster .Kubeconfig {}
254
+ bean := & bean2 .Kubeconfig {}
251
255
err = decoder .Decode (bean )
252
256
if err != nil {
253
257
impl .logger .Errorw ("request err, Validate" , "error" , err , "payload" , bean )
@@ -309,7 +313,7 @@ func (impl ClusterRestHandlerImpl) FindAll(w http.ResponseWriter, r *http.Reques
309
313
}
310
314
311
315
// RBAC enforcer applying
312
- var result []* cluster .ClusterBean
316
+ var result []* bean2 .ClusterBean
313
317
for _ , item := range clusterList {
314
318
if ok := impl .enforcer .Enforce (token , casbin .ResourceCluster , casbin .ActionGet , item .ClusterName ); ok {
315
319
result = append (result , item )
@@ -374,7 +378,7 @@ func (impl ClusterRestHandlerImpl) FindNoteByClusterId(w http.ResponseWriter, r
374
378
}
375
379
// RBAC enforcer applying
376
380
token := r .Header .Get ("token" )
377
- 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 )
378
382
if err != nil {
379
383
impl .logger .Errorw ("error in checking rbac for cluster" , "err" , err , "clusterId" , bean .ClusterId )
380
384
common .WriteJsonResp (w , err , nil , http .StatusInternalServerError )
@@ -397,7 +401,7 @@ func (impl ClusterRestHandlerImpl) Update(w http.ResponseWriter, r *http.Request
397
401
common .WriteJsonResp (w , err , "Unauthorized User" , http .StatusUnauthorized )
398
402
return
399
403
}
400
- var bean cluster .ClusterBean
404
+ var bean bean2 .ClusterBean
401
405
err = decoder .Decode (& bean )
402
406
if err != nil {
403
407
impl .logger .Errorw ("request err, Update" , "error" , err , "payload" , bean )
@@ -458,7 +462,7 @@ func (impl ClusterRestHandlerImpl) UpdateClusterDescription(w http.ResponseWrite
458
462
common .WriteJsonResp (w , err , "Unauthorized User" , http .StatusUnauthorized )
459
463
return
460
464
}
461
- var bean cluster .ClusterBean
465
+ var bean bean2 .ClusterBean
462
466
err = decoder .Decode (& bean )
463
467
if err != nil {
464
468
impl .logger .Errorw ("request err, UpdateClusterDescription" , "error" , err , "payload" , bean )
@@ -474,7 +478,8 @@ func (impl ClusterRestHandlerImpl) UpdateClusterDescription(w http.ResponseWrite
474
478
return
475
479
}
476
480
// RBAC enforcer applying
477
- 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 {
478
483
common .WriteJsonResp (w , errors .New ("unauthorized" ), nil , http .StatusForbidden )
479
484
return
480
485
}
@@ -518,7 +523,8 @@ func (impl ClusterRestHandlerImpl) UpdateClusterNote(w http.ResponseWriter, r *h
518
523
return
519
524
}
520
525
// RBAC enforcer applying
521
- 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 {
522
528
common .WriteJsonResp (w , errors .New ("unauthorized" ), nil , http .StatusForbidden )
523
529
return
524
530
}
@@ -544,7 +550,7 @@ func (impl ClusterRestHandlerImpl) FindAllForAutoComplete(w http.ResponseWriter,
544
550
common .WriteJsonResp (w , err , nil , http .StatusInternalServerError )
545
551
return
546
552
}
547
- var result []cluster .ClusterBean
553
+ var result []bean2 .ClusterBean
548
554
v := r .URL .Query ()
549
555
authEnabled := true
550
556
auth := v .Get ("auth" )
@@ -573,7 +579,7 @@ func (impl ClusterRestHandlerImpl) FindAllForAutoComplete(w http.ResponseWriter,
573
579
//RBAC enforcer Ends
574
580
575
581
if len (result ) == 0 {
576
- result = make ([]cluster .ClusterBean , 0 )
582
+ result = make ([]bean2 .ClusterBean , 0 )
577
583
}
578
584
common .WriteJsonResp (w , err , result , http .StatusOK )
579
585
}
@@ -586,7 +592,7 @@ func (impl ClusterRestHandlerImpl) DeleteCluster(w http.ResponseWriter, r *http.
586
592
common .WriteJsonResp (w , err , "Unauthorized User" , http .StatusUnauthorized )
587
593
return
588
594
}
589
- var bean cluster .ClusterBean
595
+ var bean bean2 .ClusterBean
590
596
err = decoder .Decode (& bean )
591
597
if err != nil {
592
598
impl .logger .Errorw ("request err, Delete" , "error" , err , "payload" , bean )
@@ -619,17 +625,61 @@ func (impl ClusterRestHandlerImpl) DeleteCluster(w http.ResponseWriter, r *http.
619
625
620
626
func (impl ClusterRestHandlerImpl ) GetAllClusterNamespaces (w http.ResponseWriter , r * http.Request ) {
621
627
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
+ }
622
634
clusterNamespaces := impl .clusterService .GetAllClusterNamespaces ()
623
635
624
636
// RBAC enforcer applying
625
- for clusterName , _ := range clusterNamespaces {
626
- if ok := impl .enforcer .Enforce (token , casbin .ResourceCluster , casbin .ActionGet , clusterName ); ! ok {
627
- delete (clusterNamespaces , clusterName )
628
- }
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
629
642
}
630
643
//RBAC enforcer Ends
631
644
632
- 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
+
633
683
}
634
684
635
685
func (impl ClusterRestHandlerImpl ) GetClusterNamespaces (w http.ResponseWriter , r * http.Request ) {
@@ -688,7 +738,7 @@ func (impl ClusterRestHandlerImpl) FindAllForClusterPermission(w http.ResponseWr
688
738
if len (clusterList ) == 0 {
689
739
// assumption is that if list is empty, then it can happen only in case of Unauthorized (but not sending Unauthorized for super-admin user)
690
740
if isActionUserSuperAdmin {
691
- clusterList = make ([]cluster .ClusterBean , 0 )
741
+ clusterList = make ([]bean2 .ClusterBean , 0 )
692
742
} else {
693
743
common .WriteJsonResp (w , errors .New ("unauthorized" ), nil , http .StatusForbidden )
694
744
return
0 commit comments