Skip to content
Merged
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
feed684
added app group api's
vikramdevtron Apr 13, 2023
c9f35ed
Merge branch 'main' into custom-app-grouping
vikramdevtron Apr 13, 2023
3370c17
db migration and api added for app group
vikramdevtron Apr 13, 2023
c5d92f0
app grouping apis modified and added handling for custom app group
vikramdevtron Apr 14, 2023
1a9e508
fix
vikramdevtron Apr 14, 2023
c09fe0e
added delete api for app group and app group id support
vikramdevtron Apr 14, 2023
304909f
app grouping api's handling app group id and app ids
vikramdevtron Apr 15, 2023
999b51b
Merge branch 'main' into custom-app-grouping
vikramdevtron Apr 15, 2023
8aed051
description in app group
vikramdevtron Apr 17, 2023
79530a0
added ci and cd min apis for app group
vikramdevtron Apr 17, 2023
1c531bc
changes in min cd pipeline api
vikramdevtron Apr 17, 2023
ed76913
fix
vikramdevtron Apr 17, 2023
949a63c
auth changes for custom app grouping and db migration updated
vikramdevtron Apr 18, 2023
a41028d
Merge branch 'main' into custom-app-grouping
vikramdevtron Apr 18, 2023
3d8211a
db migration seq fixed
vikramdevtron Apr 18, 2023
b9bfdf0
while delete app group, renmaed and marked deleted
vikramdevtron Apr 18, 2023
134dc5f
admin check removed for app group
vikramdevtron Apr 18, 2023
d10b098
remove app group if has no app authorized
vikramdevtron Apr 18, 2023
bc806ee
duplicate and delete fix
vikramdevtron Apr 18, 2023
cac9a86
changes after qa
vikramdevtron Apr 18, 2023
5706484
added more detail in ci min api
vikramdevtron Apr 18, 2023
19aa544
added more detail in ci min api
vikramdevtron Apr 18, 2023
ef44976
fix
vikramdevtron Apr 18, 2023
dfba27b
conflicts resolve and create app group status code modified
vikramdevtron Apr 19, 2023
aa7ce2f
remove eliminated item from app group update
vikramdevtron Apr 19, 2023
00975d0
Merge branch 'main' into custom-app-grouping
vikramdevtron Apr 20, 2023
af91a11
fix post cd not triggered
vikramdevtron Apr 20, 2023
54c8834
fix for ci pipeline min
vikramdevtron Apr 20, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions Wire.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ import (
"github.com/devtron-labs/devtron/client/telemetry"
"github.com/devtron-labs/devtron/internal/sql/repository"
app2 "github.com/devtron-labs/devtron/internal/sql/repository/app"
appGroup2 "github.com/devtron-labs/devtron/internal/sql/repository/appGroup"
appStatusRepo "github.com/devtron-labs/devtron/internal/sql/repository/appStatus"
appWorkflow2 "github.com/devtron-labs/devtron/internal/sql/repository/appWorkflow"
"github.com/devtron-labs/devtron/internal/sql/repository/bulkUpdate"
Expand All @@ -75,6 +76,7 @@ import (
"github.com/devtron-labs/devtron/pkg/app"
"github.com/devtron-labs/devtron/pkg/appClone"
"github.com/devtron-labs/devtron/pkg/appClone/batch"
"github.com/devtron-labs/devtron/pkg/appGroup"
"github.com/devtron-labs/devtron/pkg/appStatus"
appStoreBean "github.com/devtron-labs/devtron/pkg/appStore/bean"
appStoreDeploymentFullMode "github.com/devtron-labs/devtron/pkg/appStore/deployment/fullMode"
Expand Down Expand Up @@ -827,6 +829,14 @@ func InitializeApp() (*App, error) {

router.NewAppGroupingRouterImpl,
wire.Bind(new(router.AppGroupingRouter), new(*router.AppGroupingRouterImpl)),
restHandler.NewAppGroupRestHandlerImpl,
wire.Bind(new(restHandler.AppGroupRestHandler), new(*restHandler.AppGroupRestHandlerImpl)),
appGroup.NewAppGroupServiceImpl,
wire.Bind(new(appGroup.AppGroupService), new(*appGroup.AppGroupServiceImpl)),
appGroup2.NewAppGroupRepositoryImpl,
wire.Bind(new(appGroup2.AppGroupRepository), new(*appGroup2.AppGroupRepositoryImpl)),
appGroup2.NewAppGroupMappingRepositoryImpl,
wire.Bind(new(appGroup2.AppGroupMappingRepository), new(*appGroup2.AppGroupMappingRepositoryImpl)),
)
return &App{}, nil
}
225 changes: 225 additions & 0 deletions api/restHandler/AppGroupRestHandler.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,225 @@
/*
* Copyright (c) 2020 Devtron Labs
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/

package restHandler

import (
"encoding/json"
"errors"
"github.com/devtron-labs/devtron/api/restHandler/common"
"github.com/devtron-labs/devtron/pkg/appGroup"
"github.com/devtron-labs/devtron/pkg/user"
"github.com/devtron-labs/devtron/pkg/user/casbin"
"github.com/gorilla/mux"
"go.uber.org/zap"
"gopkg.in/go-playground/validator.v9"
"net/http"
"strconv"
"strings"
)

type AppGroupRestHandler interface {
GetActiveAppGroupList(w http.ResponseWriter, r *http.Request)
GetApplicationsForAppGroup(w http.ResponseWriter, r *http.Request)
CreateAppGroup(w http.ResponseWriter, r *http.Request)
UpdateAppGroup(w http.ResponseWriter, r *http.Request)
DeleteAppGroup(w http.ResponseWriter, r *http.Request)
}

type AppGroupRestHandlerImpl struct {
logger *zap.SugaredLogger
enforcer casbin.Enforcer
userService user.UserService
appGroupService appGroup.AppGroupService
validator *validator.Validate
}

func NewAppGroupRestHandlerImpl(logger *zap.SugaredLogger, enforcer casbin.Enforcer,
userService user.UserService, appGroupService appGroup.AppGroupService,
validator *validator.Validate) *AppGroupRestHandlerImpl {
userAuthHandler := &AppGroupRestHandlerImpl{
logger: logger,
enforcer: enforcer,
userService: userService,
appGroupService: appGroupService,
validator: validator,
}
return userAuthHandler
}

func (handler AppGroupRestHandlerImpl) GetActiveAppGroupList(w http.ResponseWriter, r *http.Request) {
userId, err := handler.userService.GetLoggedInUser(r)
if userId == 0 || err != nil {
common.WriteJsonResp(w, err, "Unauthorized User", http.StatusUnauthorized)
return
}
user, err := handler.userService.GetById(userId)
if userId == 0 || err != nil {
common.WriteJsonResp(w, err, "Unauthorized User", http.StatusUnauthorized)
return
}
emailId := strings.ToLower(user.EmailId)
vars := mux.Vars(r)
envId, err := strconv.Atoi(vars["envId"])
if err != nil {
common.WriteJsonResp(w, err, nil, http.StatusBadRequest)
return
}
res, err := handler.appGroupService.GetActiveAppGroupList(emailId, handler.checkAuthBatch, envId)
if err != nil {
handler.logger.Errorw("service err, GetActiveAppGroupList", "err", err)
common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
return
}
common.WriteJsonResp(w, nil, res, http.StatusOK)
}
func (handler AppGroupRestHandlerImpl) GetApplicationsForAppGroup(w http.ResponseWriter, r *http.Request) {
userId, err := handler.userService.GetLoggedInUser(r)
if userId == 0 || err != nil {
common.WriteJsonResp(w, err, "Unauthorized User", http.StatusUnauthorized)
return
}
token := r.Header.Get("token")
if ok := handler.enforcer.Enforce(token, casbin.ResourceGlobal, casbin.ActionGet, "*"); !ok {
common.WriteJsonResp(w, errors.New("unauthorized"), nil, http.StatusForbidden)
return
}
vars := mux.Vars(r)
id, err := strconv.Atoi(vars["appGroupId"])
if err != nil {
common.WriteJsonResp(w, err, "", http.StatusBadRequest)
return
}
res, err := handler.appGroupService.GetApplicationsForAppGroup(id)
if err != nil {
handler.logger.Errorw("service err, GetApplicationsForAppGroup", "err", err)
common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
return
}
common.WriteJsonResp(w, nil, res, http.StatusOK)
}
func (handler AppGroupRestHandlerImpl) CreateAppGroup(w http.ResponseWriter, r *http.Request) {
userId, err := handler.userService.GetLoggedInUser(r)
if userId == 0 || err != nil {
common.WriteJsonResp(w, err, "Unauthorized User", http.StatusUnauthorized)
return
}
decoder := json.NewDecoder(r.Body)
var request appGroup.AppGroupDto
err = decoder.Decode(&request)
if err != nil {
handler.logger.Errorw("request err, CreateAppGroup", "err", err, "payload", request)
common.WriteJsonResp(w, err, nil, http.StatusBadRequest)
return
}
request.UserId = userId
vars := mux.Vars(r)
envId, err := strconv.Atoi(vars["envId"])
if err != nil {
common.WriteJsonResp(w, err, nil, http.StatusBadRequest)
return
}
request.EnvironmentId = envId
err = handler.validator.Struct(request)
if err != nil {
handler.logger.Errorw("validation error", "err", err, "payload", request)
common.WriteJsonResp(w, err, nil, http.StatusBadRequest)
return
}
token := r.Header.Get("token")
if ok := handler.enforcer.Enforce(token, casbin.ResourceGlobal, casbin.ActionCreate, "*"); !ok {
common.WriteJsonResp(w, errors.New("unauthorized"), nil, http.StatusForbidden)
return
}
handler.logger.Infow("request payload, CreateAppGroup", "payload", request)
resp, err := handler.appGroupService.CreateAppGroup(&request)
if err != nil {
handler.logger.Errorw("service err, CreateAppGroup", "err", err, "payload", request)
common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
return
}
common.WriteJsonResp(w, nil, resp, http.StatusOK)
}
func (handler AppGroupRestHandlerImpl) UpdateAppGroup(w http.ResponseWriter, r *http.Request) {
userId, err := handler.userService.GetLoggedInUser(r)
if userId == 0 || err != nil {
common.WriteJsonResp(w, err, "Unauthorized User", http.StatusUnauthorized)
return
}
decoder := json.NewDecoder(r.Body)
var request appGroup.AppGroupDto
err = decoder.Decode(&request)
if err != nil {
handler.logger.Errorw("request err, UpdateAppGroup", "err", err, "payload", request)
common.WriteJsonResp(w, err, nil, http.StatusBadRequest)
return
}
request.UserId = userId
err = handler.validator.Struct(request)
if err != nil {
handler.logger.Errorw("validation error", "err", err, "payload", request)
common.WriteJsonResp(w, err, nil, http.StatusBadRequest)
return
}
token := r.Header.Get("token")
if ok := handler.enforcer.Enforce(token, casbin.ResourceGlobal, casbin.ActionUpdate, "*"); !ok {
common.WriteJsonResp(w, errors.New("unauthorized"), nil, http.StatusForbidden)
return
}
handler.logger.Infow("request payload, UpdateAppGroup", "payload", request)
resp, err := handler.appGroupService.UpdateAppGroup(&request)
if err != nil {
handler.logger.Errorw("service err, UpdateAppGroup", "err", err, "payload", request)
common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
return
}
common.WriteJsonResp(w, nil, resp, http.StatusOK)
}
func (handler AppGroupRestHandlerImpl) DeleteAppGroup(w http.ResponseWriter, r *http.Request) {
userId, err := handler.userService.GetLoggedInUser(r)
if userId == 0 || err != nil {
common.WriteJsonResp(w, err, "Unauthorized User", http.StatusUnauthorized)
return
}
vars := mux.Vars(r)
appGroupId, err := strconv.Atoi(vars["appGroupId"])
if err != nil {
common.WriteJsonResp(w, err, "", http.StatusBadRequest)
return
}
token := r.Header.Get("token")
if ok := handler.enforcer.Enforce(token, casbin.ResourceGlobal, casbin.ActionDelete, "*"); !ok {
common.WriteJsonResp(w, errors.New("unauthorized"), nil, http.StatusForbidden)
return
}
handler.logger.Infow("request payload, DeleteAppGroup", "appGroupId", appGroupId)
resp, err := handler.appGroupService.DeleteAppGroup(appGroupId)
if err != nil {
handler.logger.Errorw("service err, DeleteAppGroup", "err", err, "appGroupId", appGroupId)
common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
return
}
common.WriteJsonResp(w, nil, resp, http.StatusOK)
}

func (handler AppGroupRestHandlerImpl) checkAuthBatch(emailId string, appObject []string) map[string]bool {
var appResult map[string]bool
if len(appObject) > 0 {
appResult = handler.enforcer.EnforceByEmailInBatch(emailId, casbin.ResourceApplications, casbin.ActionGet, appObject)
}
return appResult
}
36 changes: 35 additions & 1 deletion api/restHandler/AppWorkflowRestHandler.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"github.com/devtron-labs/devtron/internal/sql/repository/app"
appWorkflow2 "github.com/devtron-labs/devtron/internal/sql/repository/appWorkflow"
"github.com/devtron-labs/devtron/internal/util"
appGroup2 "github.com/devtron-labs/devtron/pkg/appGroup"
"github.com/devtron-labs/devtron/pkg/appWorkflow"
"github.com/devtron-labs/devtron/pkg/bean"
"github.com/devtron-labs/devtron/pkg/pipeline"
Expand Down Expand Up @@ -242,9 +243,42 @@ func (impl AppWorkflowRestHandlerImpl) FindAppWorkflowByEnvironment(w http.Respo
common.WriteJsonResp(w, err, nil, http.StatusBadRequest)
return
}

v := r.URL.Query()
appIdsString := v.Get("appIds")
var appIds []int
if len(appIdsString) > 0 {
appIdsSlices := strings.Split(appIdsString, ",")
for _, appId := range appIdsSlices {
id, err := strconv.Atoi(appId)
if err != nil {
common.WriteJsonResp(w, err, "please provide valid appIds", http.StatusBadRequest)
return
}
appIds = append(appIds, id)
}
}
var appGroupId int
appGroupIdStr := v.Get("appGroupId")
if len(appGroupIdStr) > 0 {
appGroupId, err = strconv.Atoi(appGroupIdStr)
if err != nil {
common.WriteJsonResp(w, err, "please provide valid appGroupId", http.StatusBadRequest)
return
}
}
request := appGroup2.AppGroupingRequest{
EnvId: envId,
AppGroupId: appGroupId,
AppIds: appIds,
EmailId: userEmailId,
CheckAuthBatch: impl.checkAuthBatch,
UserId: userId,
Ctx: r.Context(),
}
workflows := make(map[string]interface{})
_, span := otel.Tracer("orchestrator").Start(r.Context(), "ciHandler.FetchAppWorkflowsInAppGrouping")
workflowsList, err := impl.appWorkflowService.FindAppWorkflowsByEnvironmentId(envId, userEmailId, impl.checkAuthBatch)
workflowsList, err := impl.appWorkflowService.FindAppWorkflowsByEnvironmentId(request)
span.End()
if err != nil {
impl.Logger.Errorw("error in fetching workflows for app", "err", err)
Expand Down
Loading