Skip to content

Commit 9880939

Browse files
committed
review comments.
2 parents 05817b0 + 73f1aa5 commit 9880939

File tree

80 files changed

+3047
-295
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

80 files changed

+3047
-295
lines changed

api/appStore/AppStoreRouter.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,9 @@ func (router AppStoreRouterImpl) Init(configRouter *mux.Router) {
7676
configRouter.Path("/installed-app/detail").Queries("installed-app-id", "{installed-app-id}").Queries("env-id", "{env-id}").
7777
HandlerFunc(router.deployRestHandler.FetchAppDetailsForInstalledApp).
7878
Methods("GET")
79+
configRouter.Path("/installed-app/delete/{installedAppId}/non-cascade").
80+
HandlerFunc(router.deployRestHandler.DeleteArgoInstalledAppWithNonCascade).
81+
Methods("DELETE")
7982
configRouter.Path("/installed-app/detail/v2").Queries("installed-app-id", "{installed-app-id}").Queries("env-id", "{env-id}").
8083
HandlerFunc(router.deployRestHandler.FetchAppDetailsForInstalledAppV2).
8184
Methods("GET")

api/appStore/InstalledAppRestHandler.go

Lines changed: 82 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
package appStore
1919

2020
import (
21+
"context"
2122
"encoding/json"
2223
"errors"
2324
"fmt"
@@ -36,6 +37,7 @@ import (
3637
"github.com/devtron-labs/devtron/pkg/cluster"
3738
"github.com/devtron-labs/devtron/pkg/user"
3839
"github.com/devtron-labs/devtron/pkg/user/casbin"
40+
"github.com/devtron-labs/devtron/util"
3941
"github.com/devtron-labs/devtron/util/argo"
4042
"github.com/devtron-labs/devtron/util/rbac"
4143
"github.com/devtron-labs/devtron/util/response"
@@ -55,6 +57,7 @@ type InstalledAppRestHandler interface {
5557
CheckAppExists(w http.ResponseWriter, r *http.Request)
5658
DefaultComponentInstallation(w http.ResponseWriter, r *http.Request)
5759
FetchAppDetailsForInstalledApp(w http.ResponseWriter, r *http.Request)
60+
DeleteArgoInstalledAppWithNonCascade(w http.ResponseWriter, r *http.Request)
5861
FetchAppDetailsForInstalledAppV2(w http.ResponseWriter, r *http.Request)
5962
FetchResourceTree(w http.ResponseWriter, r *http.Request)
6063
FetchResourceTreeForACDApp(w http.ResponseWriter, r *http.Request)
@@ -66,6 +69,7 @@ type InstalledAppRestHandlerImpl struct {
6669
userAuthService user.UserService
6770
enforcer casbin.Enforcer
6871
enforcerUtil rbac.EnforcerUtil
72+
enforcerUtilHelm rbac.EnforcerUtilHelm
6973
installedAppService service.InstalledAppService
7074
validator *validator.Validate
7175
clusterService cluster.ClusterService
@@ -79,7 +83,7 @@ type InstalledAppRestHandlerImpl struct {
7983
}
8084

8185
func NewInstalledAppRestHandlerImpl(Logger *zap.SugaredLogger, userAuthService user.UserService,
82-
enforcer casbin.Enforcer, enforcerUtil rbac.EnforcerUtil, installedAppService service.InstalledAppService,
86+
enforcer casbin.Enforcer, enforcerUtil rbac.EnforcerUtil, enforcerUtilHelm rbac.EnforcerUtilHelm, installedAppService service.InstalledAppService,
8387
validator *validator.Validate, clusterService cluster.ClusterService, acdServiceClient application.ServiceClient,
8488
appStoreDeploymentService service.AppStoreDeploymentService, helmAppClient client.HelmAppClient, helmAppService client.HelmAppService,
8589
argoUserService argo.ArgoUserService,
@@ -91,6 +95,7 @@ func NewInstalledAppRestHandlerImpl(Logger *zap.SugaredLogger, userAuthService u
9195
userAuthService: userAuthService,
9296
enforcer: enforcer,
9397
enforcerUtil: enforcerUtil,
98+
enforcerUtilHelm: enforcerUtilHelm,
9499
installedAppService: installedAppService,
95100
validator: validator,
96101
clusterService: clusterService,
@@ -429,6 +434,82 @@ func (handler *InstalledAppRestHandlerImpl) FetchNotesForArgoInstalledApp(w http
429434
common.WriteJsonResp(w, err, &bean2.Notes{Notes: notes}, http.StatusOK)
430435

431436
}
437+
438+
func (handler *InstalledAppRestHandlerImpl) DeleteArgoInstalledAppWithNonCascade(w http.ResponseWriter, r *http.Request) {
439+
token := r.Header.Get("token")
440+
userId, err := handler.userAuthService.GetLoggedInUser(r)
441+
if userId == 0 || err != nil {
442+
common.WriteJsonResp(w, err, nil, http.StatusUnauthorized)
443+
return
444+
}
445+
vars := mux.Vars(r)
446+
installedAppId, err := strconv.Atoi(vars["installedAppId"])
447+
if err != nil {
448+
handler.Logger.Errorw("request err, DeleteArgoInstalledAppWithNonCascade", "err", err, "installedAppId", installedAppId)
449+
common.WriteJsonResp(w, err, nil, http.StatusBadRequest)
450+
return
451+
}
452+
handler.Logger.Infow("request payload, delete app", "appId", installedAppId)
453+
v := r.URL.Query()
454+
forceDelete := false
455+
force := v.Get("force")
456+
if len(force) > 0 {
457+
forceDelete, err = strconv.ParseBool(force)
458+
if err != nil {
459+
handler.Logger.Errorw("request err, NonCascadeDeleteCdPipeline", "err", err)
460+
common.WriteJsonResp(w, err, nil, http.StatusBadRequest)
461+
return
462+
}
463+
}
464+
installedApp, err := handler.appStoreDeploymentService.GetInstalledApp(installedAppId)
465+
if err != nil {
466+
handler.Logger.Error("request err, NonCascadeDeleteCdPipeline", "err", err)
467+
common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
468+
return
469+
}
470+
if util.IsBaseStack() || util.IsHelmApp(installedApp.AppOfferingMode) || util2.IsHelmApp(installedApp.DeploymentAppType) {
471+
handler.Logger.Errorw("request err, NonCascadeDeleteCdPipeline", "err", fmt.Errorf("nocascade delete is not supported for %s", installedApp.AppName))
472+
common.WriteJsonResp(w, err, nil, http.StatusBadRequest)
473+
return
474+
}
475+
//rbac block starts from here
476+
rbacObject, rbacObject2 := handler.enforcerUtil.GetHelmObjectByAppNameAndEnvId(installedApp.AppName, installedApp.EnvironmentId)
477+
ok := handler.enforcer.Enforce(token, casbin.ResourceHelmApp, casbin.ActionDelete, rbacObject) || handler.enforcer.Enforce(token, casbin.ResourceHelmApp, casbin.ActionDelete, rbacObject2)
478+
if !ok {
479+
common.WriteJsonResp(w, fmt.Errorf("unauthorized user"), nil, http.StatusForbidden)
480+
return
481+
}
482+
//rback block ends here
483+
acdToken, err := handler.argoUserService.GetLatestDevtronArgoCdUserToken()
484+
if err != nil {
485+
handler.Logger.Errorw("error in getting acd token", "err", err)
486+
common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
487+
return
488+
}
489+
ctx := context.WithValue(r.Context(), "token", acdToken)
490+
request := &appStoreBean.InstallAppVersionDTO{}
491+
request.InstalledAppId = installedAppId
492+
request.AppName = installedApp.AppName
493+
request.AppId = installedApp.AppId
494+
request.EnvironmentId = installedApp.EnvironmentId
495+
request.UserId = userId
496+
request.ForceDelete = forceDelete
497+
request.NonCascadeDelete = true
498+
request.AppOfferingMode = installedApp.AppOfferingMode
499+
request.ClusterId = installedApp.ClusterId
500+
request.Namespace = installedApp.Namespace
501+
request.AcdPartialDelete = true
502+
503+
request, err = handler.appStoreDeploymentService.DeleteInstalledApp(ctx, request)
504+
if err != nil {
505+
handler.Logger.Errorw("service err, DeleteInstalledApp", "err", err, "installAppId", installedAppId)
506+
common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
507+
return
508+
}
509+
common.WriteJsonResp(w, nil, nil, http.StatusOK)
510+
511+
}
512+
432513
func (handler *InstalledAppRestHandlerImpl) checkNotesAuth(token string, appName string, envId int) bool {
433514

434515
object, object2 := handler.enforcerUtil.GetHelmObjectByAppNameAndEnvId(appName, envId)

api/appStore/deployment/AppStoreDeploymentRestHandler.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,12 +256,25 @@ func (handler AppStoreDeploymentRestHandlerImpl) DeleteInstalledApp(w http.Respo
256256
v := r.URL.Query()
257257
forceDelete := false
258258
force := v.Get("force")
259+
cascadeDelete := true
260+
cascade := v.Get("cascade")
261+
if len(force) > 0 && len(cascade) > 0 {
262+
handler.Logger.Errorw("request err, PatchCdPipeline", "err", fmt.Errorf("cannot perform both cascade and force delete"), "installAppId", installAppId)
263+
common.WriteJsonResp(w, fmt.Errorf("invalid query params! cannot perform both force and cascade together"), nil, http.StatusBadRequest)
264+
return
265+
}
259266
if len(force) > 0 {
260267
forceDelete, err = strconv.ParseBool(force)
261268
if err != nil {
262269
common.WriteJsonResp(w, err, nil, http.StatusBadRequest)
263270
return
264271
}
272+
} else if len(cascade) > 0 {
273+
cascadeDelete, err = strconv.ParseBool(cascade)
274+
if err != nil {
275+
common.WriteJsonResp(w, err, nil, http.StatusBadRequest)
276+
return
277+
}
265278
}
266279
partialDelete := false
267280
partialDeleteStr := v.Get("partialDelete")
@@ -311,6 +324,7 @@ func (handler AppStoreDeploymentRestHandlerImpl) DeleteInstalledApp(w http.Respo
311324
request.EnvironmentId = installedApp.EnvironmentId
312325
request.UserId = userId
313326
request.ForceDelete = forceDelete
327+
request.NonCascadeDelete = !cascadeDelete
314328
request.AppOfferingMode = installedApp.AppOfferingMode
315329
request.ClusterId = installedApp.ClusterId
316330
request.Namespace = installedApp.Namespace

api/cluster/EnvironmentRestHandler.go

Lines changed: 83 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,11 @@
1818
package cluster
1919

2020
import (
21+
"context"
2122
"encoding/json"
23+
"github.com/devtron-labs/devtron/internal/util"
24+
"github.com/devtron-labs/devtron/util/k8s"
25+
"k8s.io/client-go/kubernetes"
2226
"net/http"
2327
"strconv"
2428
"strings"
@@ -49,12 +53,14 @@ type EnvironmentRestHandler interface {
4953
FindById(w http.ResponseWriter, r *http.Request)
5054
GetEnvironmentListForAutocomplete(w http.ResponseWriter, r *http.Request)
5155
GetCombinedEnvironmentListForDropDown(w http.ResponseWriter, r *http.Request)
56+
GetEnvironmentConnection(w http.ResponseWriter, r *http.Request)
5257
DeleteEnvironment(w http.ResponseWriter, r *http.Request)
5358
GetCombinedEnvironmentListForDropDownByClusterIds(w http.ResponseWriter, r *http.Request)
5459
}
5560

5661
type EnvironmentRestHandlerImpl struct {
5762
environmentClusterMappingsService request.EnvironmentService
63+
k8sApplicationService k8s.K8sApplicationService
5864
logger *zap.SugaredLogger
5965
userService user.UserService
6066
validator *validator.Validate
@@ -63,7 +69,12 @@ type EnvironmentRestHandlerImpl struct {
6369
cfg *bean.Config
6470
}
6571

66-
func NewEnvironmentRestHandlerImpl(svc request.EnvironmentService, logger *zap.SugaredLogger, userService user.UserService,
72+
type ClusterReachableResponse struct {
73+
ClusterReachable bool `json:"clusterReachable"`
74+
ClusterName string `json:"clusterName"`
75+
}
76+
77+
func NewEnvironmentRestHandlerImpl(svc request.EnvironmentService, k8sApplicationService k8s.K8sApplicationService, logger *zap.SugaredLogger, userService user.UserService,
6778
validator *validator.Validate, enforcer casbin.Enforcer,
6879
deleteService delete2.DeleteService,
6980
) *EnvironmentRestHandlerImpl {
@@ -76,6 +87,7 @@ func NewEnvironmentRestHandlerImpl(svc request.EnvironmentService, logger *zap.S
7687
logger.Infow("evironment rest handler initialized", "ignoreAuthCheckValue", cfg.IgnoreAuthCheck)
7788
return &EnvironmentRestHandlerImpl{
7889
environmentClusterMappingsService: svc,
90+
k8sApplicationService: k8sApplicationService,
7991
logger: logger,
8092
userService: userService,
8193
validator: validator,
@@ -460,3 +472,73 @@ func (impl EnvironmentRestHandlerImpl) GetCombinedEnvironmentListForDropDownByCl
460472
}
461473
common.WriteJsonResp(w, err, clusters, http.StatusOK)
462474
}
475+
476+
func (impl EnvironmentRestHandlerImpl) GetEnvironmentConnection(w http.ResponseWriter, r *http.Request) {
477+
//token := r.Header.Get("token")
478+
vars := mux.Vars(r)
479+
envIdString := vars["envId"]
480+
envId, err := strconv.Atoi(envIdString)
481+
if err != nil {
482+
impl.logger.Errorw("failed to extract clusterId from param", "error", err, "clusterId", envIdString)
483+
common.WriteJsonResp(w, err, nil, http.StatusBadRequest)
484+
return
485+
}
486+
userId, err := impl.userService.GetLoggedInUser(r)
487+
if userId == 0 || err != nil {
488+
impl.logger.Errorw("user not authorized", "error", err, "userId", userId)
489+
common.WriteJsonResp(w, err, "Unauthorized User", http.StatusUnauthorized)
490+
return
491+
}
492+
bean, err := impl.environmentClusterMappingsService.FindById(envId)
493+
if err != nil {
494+
impl.logger.Errorw("request err, FindById", "err", err, "envId", envId)
495+
common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
496+
return
497+
}
498+
clusterBean, err := impl.environmentClusterMappingsService.FindClusterByEnvId(bean.ClusterId)
499+
if err != nil {
500+
impl.logger.Errorw("request err, FindById", "err", err, "envId", envId)
501+
common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
502+
return
503+
}
504+
// RBAC enforcer applying
505+
token := r.Header.Get("token")
506+
if ok := impl.enforcer.Enforce(token, casbin.ResourceGlobalEnvironment, casbin.ActionGet, strings.ToLower(bean.EnvironmentIdentifier)); !ok {
507+
common.WriteJsonResp(w, errors.New("unauthorized"), nil, http.StatusForbidden)
508+
return
509+
}
510+
//RBAC enforcer Ends
511+
// getting restConfig and clientSet outside the goroutine because we don't want to call goroutine func with receiver function
512+
restConfig, err := impl.k8sApplicationService.GetRestConfigByClusterId(context.Background(), clusterBean.Id)
513+
if err != nil {
514+
impl.logger.Errorw("error in getting restConfig by cluster", "err", err, "clusterId", clusterBean.Id)
515+
common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
516+
return
517+
}
518+
k8sHttpClient, err := util.OverrideK8sHttpClientWithTracer(restConfig)
519+
if err != nil {
520+
impl.logger.Errorw("service err, OverrideK8sHttpClientWithTracer", "err", err, "restConfig", restConfig)
521+
common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
522+
return
523+
}
524+
k8sClientSet, err := kubernetes.NewForConfigAndClient(restConfig, k8sHttpClient)
525+
if err != nil {
526+
impl.logger.Errorw("error in getting client set by rest config", "err", err, "restConfig", restConfig)
527+
common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
528+
return
529+
}
530+
responseObj := &ClusterReachableResponse{
531+
ClusterReachable: true,
532+
ClusterName: clusterBean.ClusterName,
533+
}
534+
err = impl.k8sApplicationService.FetchConnectionStatusForCluster(k8sClientSet, clusterBean.Id)
535+
if err != nil {
536+
responseObj.ClusterReachable = false
537+
}
538+
//updating the cluster connection error to db
539+
mapObj := map[int]error{
540+
clusterBean.Id: err,
541+
}
542+
impl.environmentClusterMappingsService.HandleErrorInClusterConnections([]*request.ClusterBean{clusterBean}, mapObj, true)
543+
common.WriteJsonResp(w, nil, responseObj, http.StatusOK)
544+
}

api/cluster/EnvironmentRouter.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,5 +71,7 @@ func (impl EnvironmentRouterImpl) InitEnvironmentClusterMappingsRouter(environme
7171
environmentClusterMappingsRouter.Path("/namespace/autocomplete").
7272
Methods("GET").
7373
HandlerFunc(impl.environmentClusterMappingsRestHandler.GetCombinedEnvironmentListForDropDownByClusterIds)
74-
74+
environmentClusterMappingsRouter.Path("/{envId}/connection").
75+
Methods("GET").
76+
HandlerFunc(impl.environmentClusterMappingsRestHandler.GetEnvironmentConnection)
7577
}

api/helm-app/HelmAppService.go

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@ import (
44
"context"
55
"errors"
66
"fmt"
7+
"net/http"
8+
"reflect"
9+
"strconv"
10+
"strings"
11+
"time"
12+
713
"github.com/caarlos0/env/v6"
814
"github.com/devtron-labs/devtron/api/connector"
915
openapi "github.com/devtron-labs/devtron/api/helm-app/openapiClient"
@@ -23,17 +29,12 @@ import (
2329
util2 "github.com/devtron-labs/devtron/util"
2430
"github.com/devtron-labs/devtron/util/rbac"
2531
jsonpatch "github.com/evanphx/json-patch"
26-
"github.com/ghodss/yaml"
2732
"github.com/gogo/protobuf/proto"
2833
"github.com/tidwall/gjson"
2934
"github.com/tidwall/sjson"
3035
"go.opentelemetry.io/otel"
3136
"go.uber.org/zap"
32-
"net/http"
33-
"reflect"
34-
"strconv"
35-
"strings"
36-
"time"
37+
"sigs.k8s.io/yaml"
3738
)
3839

3940
type HelmAppService interface {

api/restHandler/BulkUpdateRestHandler.go

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -422,19 +422,11 @@ func (handler BulkUpdateRestHandlerImpl) HandleCdPipelineBulkAction(w http.Respo
422422
return
423423
}
424424

425-
v := r.URL.Query()
426-
forceDelete := false
427-
forceDeleteParam := v.Get("forceDelete")
428-
if len(forceDeleteParam) > 0 {
429-
forceDelete, err = strconv.ParseBool(forceDeleteParam)
430-
if err != nil {
431-
handler.logger.Errorw("request err, HandleCdPipelineBulkAction", "err", err, "payload", cdPipelineBulkActionReq)
432-
common.WriteJsonResp(w, err, nil, http.StatusBadRequest)
433-
return
434-
}
425+
if cdPipelineBulkActionReq.ForceDelete {
426+
cdPipelineBulkActionReq.NonCascadeDelete = true
435427
}
436-
cdPipelineBulkActionReq.ForceDelete = forceDelete
437428

429+
v := r.URL.Query()
438430
dryRun := false
439431
dryRunParam := v.Get("dryRun")
440432
if len(dryRunParam) > 0 {

0 commit comments

Comments
 (0)