@@ -43,6 +43,8 @@ const CLUSTER_DELETE_SUCCESS_RESP = "Cluster deleted successfully."
4343
4444type ClusterRestHandler interface {
4545 Save (w http.ResponseWriter , r * http.Request )
46+ SaveClusters (w http.ResponseWriter , r * http.Request )
47+ ValidateKubeconfig (w http.ResponseWriter , r * http.Request )
4648 FindAll (w http.ResponseWriter , r * http.Request )
4749 FindById (w http.ResponseWriter , r * http.Request )
4850 FindNoteByClusterId (w http.ResponseWriter , r * http.Request )
@@ -92,6 +94,81 @@ func NewClusterRestHandlerImpl(clusterService cluster.ClusterService,
9294 }
9395}
9496
97+ func (impl ClusterRestHandlerImpl ) SaveClusters (w http.ResponseWriter , r * http.Request ) {
98+ token := r .Header .Get ("token" )
99+ decoder := json .NewDecoder (r .Body )
100+ userId , err := impl .userService .GetLoggedInUser (r )
101+ if userId == 0 || err != nil {
102+ common .WriteJsonResp (w , err , "Unauthorized User" , http .StatusUnauthorized )
103+ return
104+ }
105+ beans := []* cluster.ClusterBean {}
106+ err = decoder .Decode (& beans )
107+ if err != nil {
108+ impl .logger .Errorw ("request err, Save" , "error" , err , "payload" , beans )
109+ common .WriteJsonResp (w , err , nil , http .StatusBadRequest )
110+ return
111+ }
112+ // not logging bean object as it contains sensitive data
113+ impl .logger .Infow ("request payload received for save clusters" )
114+
115+ // RBAC enforcer applying
116+ isSuperAdmin , err := impl .userService .IsSuperAdmin (int (userId ))
117+ if ! isSuperAdmin || err != nil {
118+ if err != nil {
119+ impl .logger .Errorw ("request err, CheckSuperAdmin" , "err" , err , "isSuperAdmin" , isSuperAdmin )
120+ }
121+ common .WriteJsonResp (w , err , "Unauthorized User" , http .StatusForbidden )
122+ return
123+ }
124+ //RBAC enforcer Ends
125+ ctx , cancel := context .WithCancel (r .Context ())
126+ if cn , ok := w .(http.CloseNotifier ); ok {
127+ go func (done <- chan struct {}, closed <- chan bool ) {
128+ select {
129+ case <- done :
130+ case <- closed :
131+ cancel ()
132+ }
133+ }(ctx .Done (), cn .CloseNotify ())
134+ }
135+ if util2 .IsBaseStack () {
136+ ctx = context .WithValue (ctx , "token" , token )
137+ } else {
138+ acdToken , err := impl .argoUserService .GetLatestDevtronArgoCdUserToken ()
139+ if err != nil {
140+ impl .logger .Errorw ("error in getting acd token" , "err" , err )
141+ common .WriteJsonResp (w , err , nil , http .StatusInternalServerError )
142+ return
143+ }
144+ ctx = context .WithValue (ctx , "token" , acdToken )
145+ }
146+
147+ for _ , bean := range beans {
148+ l := len (bean .ServerUrl )
149+ if l > 1 && bean .ServerUrl [l - 1 :] == "/" {
150+ bean .ServerUrl = bean .ServerUrl [0 : l - 1 ]
151+ }
152+ if bean .Id != 0 {
153+ _ , err1 := impl .clusterService .Update (ctx , bean , userId )
154+ if err1 != nil {
155+ bean .ErrorInConnecting = err1 .Error ()
156+ } else {
157+ bean .ClusterUpdated = true
158+ }
159+ } else {
160+ _ , err1 := impl .clusterService .Save (ctx , bean , userId )
161+ if err1 != nil {
162+ bean .ErrorInConnecting = err1 .Error ()
163+ }
164+ }
165+ }
166+
167+ res := beans
168+
169+ common .WriteJsonResp (w , err , res , http .StatusOK )
170+ }
171+
95172func (impl ClusterRestHandlerImpl ) Save (w http.ResponseWriter , r * http.Request ) {
96173 token := r .Header .Get ("token" )
97174 decoder := json .NewDecoder (r .Body )
@@ -161,6 +238,66 @@ func (impl ClusterRestHandlerImpl) Save(w http.ResponseWriter, r *http.Request)
161238 common .WriteJsonResp (w , err , bean , http .StatusOK )
162239}
163240
241+ func (impl ClusterRestHandlerImpl ) ValidateKubeconfig (w http.ResponseWriter , r * http.Request ) {
242+ token := r .Header .Get ("token" )
243+ decoder := json .NewDecoder (r .Body )
244+ userId , err := impl .userService .GetLoggedInUser (r )
245+ if userId == 0 || err != nil {
246+ common .WriteJsonResp (w , err , "Unauthorized User" , http .StatusUnauthorized )
247+ return
248+ }
249+ bean := & cluster.Kubeconfig {}
250+ err = decoder .Decode (bean )
251+ if err != nil {
252+ impl .logger .Errorw ("request err, Validate" , "error" , err , "payload" , bean )
253+ common .WriteJsonResp (w , err , nil , http .StatusBadRequest )
254+ return
255+ }
256+
257+ err = impl .validator .Struct (bean )
258+ if err != nil {
259+ impl .logger .Errorw ("validation err, Validate" , "err" , err , "payload" , bean )
260+ common .WriteJsonResp (w , err , nil , http .StatusBadRequest )
261+ return
262+ }
263+
264+ // RBAC enforcer applying
265+ if ok := impl .enforcer .Enforce (token , casbin .ResourceCluster , casbin .ActionCreate , "*" ); ! ok {
266+ common .WriteJsonResp (w , errors .New ("unauthorized" ), nil , http .StatusForbidden )
267+ return
268+ }
269+ //RBAC enforcer Ends
270+ ctx , cancel := context .WithCancel (r .Context ())
271+ if cn , ok := w .(http.CloseNotifier ); ok {
272+ go func (done <- chan struct {}, closed <- chan bool ) {
273+ select {
274+ case <- done :
275+ case <- closed :
276+ cancel ()
277+ }
278+ }(ctx .Done (), cn .CloseNotify ())
279+ }
280+ if util2 .IsBaseStack () {
281+ ctx = context .WithValue (ctx , "token" , token )
282+ } else {
283+ acdToken , err := impl .argoUserService .GetLatestDevtronArgoCdUserToken ()
284+ if err != nil {
285+ impl .logger .Errorw ("error in getting acd token" , "err" , err )
286+ common .WriteJsonResp (w , err , nil , http .StatusInternalServerError )
287+ return
288+ }
289+ ctx = context .WithValue (ctx , "token" , acdToken )
290+ }
291+ res , err := impl .clusterService .ValidateKubeconfig (bean .Config )
292+ if err != nil {
293+ impl .logger .Errorw ("error in validating kubeconfig" )
294+ common .WriteJsonResp (w , err , nil , http .StatusInternalServerError )
295+ return
296+ }
297+
298+ common .WriteJsonResp (w , err , res , http .StatusOK )
299+ }
300+
164301func (impl ClusterRestHandlerImpl ) FindAll (w http.ResponseWriter , r * http.Request ) {
165302 token := r .Header .Get ("token" )
166303 clusterList , err := impl .clusterService .FindAllWithoutConfig ()
0 commit comments