Skip to content

Commit

Permalink
Merge branch 'main' into ci-pending-message
Browse files Browse the repository at this point in the history
  • Loading branch information
Ashish-devtron committed Nov 29, 2023
2 parents a66a307 + b5babb7 commit 649fede
Show file tree
Hide file tree
Showing 13 changed files with 355 additions and 83 deletions.
2 changes: 2 additions & 0 deletions api/bean/AppView.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,8 @@ type AppEnvironmentContainer struct {
PreStageStatus *string `json:"preStageStatus"`
PostStageStatus *string `json:"postStageStatus"`
LastDeployedTime string `json:"lastDeployedTime,omitempty"`
LastDeployedImage string `json:"lastDeployedImage,omitempty"`
LastDeployedBy string `json:"lastDeployedBy,omitempty"`
LastSuccessDeploymentDetail DeploymentDetailContainer `json:"-"`
Default bool `json:"default"`
Deleted bool `json:"deleted"`
Expand Down
14 changes: 12 additions & 2 deletions api/restHandler/BulkUpdateRestHandler.go
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ func (handler BulkUpdateRestHandlerImpl) BulkHibernate(w http.ResponseWriter, r
}
ctx := context.WithValue(r.Context(), "token", acdToken)
token := r.Header.Get("token")
response, err := handler.bulkUpdateService.BulkHibernate(&request, ctx, w, token, handler.checkAuthForBulkActions)
response, err := handler.bulkUpdateService.BulkHibernate(&request, ctx, w, token, handler.checkAuthForBulkHibernateAndUnhibernate)
if err != nil {
common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
return
Expand Down Expand Up @@ -318,7 +318,7 @@ func (handler BulkUpdateRestHandlerImpl) BulkUnHibernate(w http.ResponseWriter,
}
ctx := context.WithValue(r.Context(), "token", acdToken)
token := r.Header.Get("token")
response, err := handler.bulkUpdateService.BulkUnHibernate(&request, ctx, w, token, handler.checkAuthForBulkActions)
response, err := handler.bulkUpdateService.BulkUnHibernate(&request, ctx, w, token, handler.checkAuthForBulkHibernateAndUnhibernate)
if err != nil {
common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
return
Expand Down Expand Up @@ -406,6 +406,16 @@ func (handler BulkUpdateRestHandlerImpl) checkAuthForBulkActions(token string, a
return true
}

func (handler BulkUpdateRestHandlerImpl) checkAuthForBulkHibernateAndUnhibernate(token string, appObject string, envObject string) bool {
if ok := handler.enforcer.Enforce(token, casbin.ResourceApplications, casbin.ActionTrigger, strings.ToLower(appObject)); !ok {
return false
}
if ok := handler.enforcer.Enforce(token, casbin.ResourceEnvironment, casbin.ActionTrigger, strings.ToLower(envObject)); !ok {
return false
}
return true
}

func (handler BulkUpdateRestHandlerImpl) HandleCdPipelineBulkAction(w http.ResponseWriter, r *http.Request) {
decoder := json.NewDecoder(r.Body)
userId, err := handler.userAuthService.GetLoggedInUser(r)
Expand Down
2 changes: 1 addition & 1 deletion docs/user-guide/global-configurations/scoped-variables.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ In any piece of software or code, variables are used for holding data such as nu
Devtron offers super-admins the capability to define scoped variables (key-value pairs). It means, while the key remains the same, its value may change depending on the following context:

* **Global**: Variable value will be universally same throughout Devtron.
* **Cluster**: Variable value might differ for each Kubernetes cluster. [![](https://devtron-public-asset.s3.us-east-2.amazonaws.com/images/elements/EnterpriseTag.svg)](https://devtron.ai/pricing)
* **Cluster**: Variable value might differ for each Kubernetes cluster. <a href="https://devtron.ai/pricing" target="_blank"> <img src="https://devtron-public-asset.s3.us-east-2.amazonaws.com/images/elements/EnterpriseTag.svg"></a>
* **Environment**: Variable value might differ for each environment within a cluster, e.g., staging, dev, prod. [![](https://devtron-public-asset.s3.us-east-2.amazonaws.com/images/elements/EnterpriseTag.svg)](https://devtron.ai/pricing)
* **Application**: Variable value might differ for each application. [![](https://devtron-public-asset.s3.us-east-2.amazonaws.com/images/elements/EnterpriseTag.svg)](https://devtron.ai/pricing)
* **Environment + Application**: Variable value might differ for each application on a specific environment. [![](https://devtron-public-asset.s3.us-east-2.amazonaws.com/images/elements/EnterpriseTag.svg)](https://devtron.ai/pricing)
Expand Down
22 changes: 22 additions & 0 deletions internal/sql/repository/AppListingRepository.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ type AppListingRepository interface {
FindAppCount(isProd bool) (int, error)
FetchAppsByEnvironmentV2(appListingFilter helper.AppListingFilter) ([]*bean.AppEnvironmentContainer, int, error)
FetchOverviewAppsByEnvironment(envId, limit, offset int) ([]*bean.AppEnvironmentContainer, error)
FetchLastDeployedImage(appId, envId int) (*LastDeployed, error)
}

// below table is deprecated, not being used anywhere
Expand All @@ -75,7 +76,13 @@ type AppNameTypeIdContainerDBResponse struct {
AppId int `sql:"id"`
}

type LastDeployed struct {
LastDeployedBy string `sql:"last_deployed_by"`
LastDeployedImage string `sql:"last_deployed_image"`
}

const NewDeployment string = "Deployment Initiated"
const Hibernating string = "HIBERNATING"

type AppListingRepositoryImpl struct {
dbConnection *pg.DB
Expand Down Expand Up @@ -138,6 +145,21 @@ func (impl AppListingRepositoryImpl) FetchOverviewAppsByEnvironment(envId, limit
return envContainers, err
}

func (impl AppListingRepositoryImpl) FetchLastDeployedImage(appId, envId int) (*LastDeployed, error) {
var lastDeployed []*LastDeployed
query := `select ca.image as last_deployed_image, u.email_id as last_deployed_by from pipeline p
join cd_workflow cw on cw.pipeline_id = p.id
join cd_workflow_runner cwr on cwr.cd_workflow_id = cw.id
join ci_artifact ca on ca.id = cw.ci_artifact_id
join users u on u.id = cwr.triggered_by
where p.app_id = ? and p.environment_id = ? and p.deleted = false order by cwr.created_on desc;`
_, err := impl.dbConnection.Query(&lastDeployed, query, appId, envId)
if len(lastDeployed) > 0 {
return lastDeployed[0], err
}
return nil, err
}

func (impl AppListingRepositoryImpl) FetchJobsLastSucceededOn(CiPipelineIDs []int) ([]*bean.CiPipelineLastSucceededTime, error) {
var lastSucceededTimeArray []*bean.CiPipelineLastSucceededTime
if len(CiPipelineIDs) == 0 {
Expand Down
9 changes: 9 additions & 0 deletions internal/sql/repository/appStatus/AppStatusRepository.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ type AppStatusRepository interface {
DeleteWithEnvId(tx *pg.Tx, envId int) error
Get(appId, envId int) (AppStatusContainer, error)
GetConnection() *pg.DB
GetByEnvId(envId int) ([]*AppStatusDto, error)

//GetAllDevtronAppStatuses(appIds []int) ([]AppStatusContainer, error)
//GetAllInstalledAppStatuses(installedAppIds []int) ([]AppStatusContainer, error)
Expand Down Expand Up @@ -107,3 +108,11 @@ func (repo *AppStatusRepositoryImpl) Get(appId, envId int) (AppStatusContainer,
}
return container, err
}

func (repo *AppStatusRepositoryImpl) GetByEnvId(envId int) ([]*AppStatusDto, error) {
var models []*AppStatusDto
err := repo.dbConnection.Model(&models).
Where("env_id = ?", envId).
Select()
return models, err
}
31 changes: 31 additions & 0 deletions internal/sql/repository/pipelineConfig/PipelineRepository.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ package pipelineConfig
import (
"github.com/devtron-labs/common-lib/utils/k8s/health"
"github.com/devtron-labs/devtron/api/bean"
"github.com/devtron-labs/devtron/internal/sql/models"
"github.com/devtron-labs/devtron/internal/sql/repository/app"
"github.com/devtron-labs/devtron/internal/sql/repository/appWorkflow"
"github.com/devtron-labs/devtron/internal/util"
Expand Down Expand Up @@ -110,6 +111,7 @@ type PipelineRepository interface {
FindActiveByAppIds(appIds []int) (pipelines []*Pipeline, err error)
FindAppAndEnvironmentAndProjectByPipelineIds(pipelineIds []int) (pipelines []*Pipeline, err error)
FilterDeploymentDeleteRequestedPipelineIds(cdPipelineIds []int) (map[int]bool, error)
FindDeploymentTypeByPipelineIds(cdPipelineIds []int) (map[int]DeploymentObject, error)
}

type CiArtifactDTO struct {
Expand All @@ -122,6 +124,12 @@ type CiArtifactDTO struct {
WorkflowId *int `json:"workflowId"`
}

type DeploymentObject struct {
DeploymentType models.DeploymentType `sql:"deployment_type"`
PipelineId int `sql:"pipeline_id"`
Status string `sql:"status"`
}

type PipelineRepositoryImpl struct {
dbConnection *pg.DB
logger *zap.SugaredLogger
Expand Down Expand Up @@ -670,3 +678,26 @@ func (impl PipelineRepositoryImpl) FilterDeploymentDeleteRequestedPipelineIds(cd
}
return pipelineIdsMap, nil
}

func (impl PipelineRepositoryImpl) FindDeploymentTypeByPipelineIds(cdPipelineIds []int) (map[int]DeploymentObject, error) {

pipelineIdsMap := make(map[int]DeploymentObject)

var deploymentType []DeploymentObject
query := "with pcos as(select max(id) as id from pipeline_config_override where pipeline_id in (?) " +
"group by pipeline_id) select pco.deployment_type,pco.pipeline_id, aps.status from pipeline_config_override " +
"pco inner join pcos on pcos.id=pco.id" +
" inner join pipeline p on p.id=pco.pipeline_id left join app_status aps on aps.app_id=p.app_id " +
"and aps.env_id=p.environment_id;"

_, err := impl.dbConnection.Query(&deploymentType, query, pg.In(cdPipelineIds), true)
if err != nil {
return pipelineIdsMap, err
}

for _, v := range deploymentType {
pipelineIdsMap[v.PipelineId] = v
}

return pipelineIdsMap, nil
}
38 changes: 37 additions & 1 deletion pkg/app/AppListingService.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (
chartRepoRepository "github.com/devtron-labs/devtron/pkg/chartRepo/repository"
repository2 "github.com/devtron-labs/devtron/pkg/cluster/repository"
"github.com/devtron-labs/devtron/pkg/dockerRegistry"
userrepository "github.com/devtron-labs/devtron/pkg/user/repository"
"github.com/devtron-labs/devtron/util/argo"
errors2 "github.com/juju/errors"
"go.opentelemetry.io/otel"
Expand Down Expand Up @@ -166,6 +167,7 @@ type AppListingServiceImpl struct {
chartRepository chartRepoRepository.ChartRepository
ciPipelineRepository pipelineConfig.CiPipelineRepository
dockerRegistryIpsConfigService dockerRegistry.DockerRegistryIpsConfigService
userRepository userrepository.UserRepository
}

func NewAppListingServiceImpl(Logger *zap.SugaredLogger, appListingRepository repository.AppListingRepository,
Expand All @@ -176,7 +178,7 @@ func NewAppListingServiceImpl(Logger *zap.SugaredLogger, appListingRepository re
pipelineOverrideRepository chartConfig.PipelineOverrideRepository, environmentRepository repository2.EnvironmentRepository,
argoUserService argo.ArgoUserService, envOverrideRepository chartConfig.EnvConfigOverrideRepository,
chartRepository chartRepoRepository.ChartRepository, ciPipelineRepository pipelineConfig.CiPipelineRepository,
dockerRegistryIpsConfigService dockerRegistry.DockerRegistryIpsConfigService) *AppListingServiceImpl {
dockerRegistryIpsConfigService dockerRegistry.DockerRegistryIpsConfigService, userRepository userrepository.UserRepository) *AppListingServiceImpl {
serviceImpl := &AppListingServiceImpl{
Logger: Logger,
appListingRepository: appListingRepository,
Expand All @@ -195,6 +197,7 @@ func NewAppListingServiceImpl(Logger *zap.SugaredLogger, appListingRepository re
chartRepository: chartRepository,
ciPipelineRepository: ciPipelineRepository,
dockerRegistryIpsConfigService: dockerRegistryIpsConfigService,
userRepository: userRepository,
}
return serviceImpl
}
Expand All @@ -207,10 +210,20 @@ type OverviewAppsByEnvironmentBean struct {
EnvironmentName string `json:"environmentName"`
Namespace string `json:"namespace"`
ClusterName string `json:"clusterName"`
ClusterId int `json:"clusterId"`
Type string `json:"environmentType"`
Description string `json:"description"`
AppCount int `json:"appCount"`
Apps []*bean.AppEnvironmentContainer `json:"apps"`
CreatedOn string `json:"createdOn"`
CreatedBy string `json:"createdBy"`
}

const (
Production = "Production"
NonProduction = "Non-Production"
)

func (impl AppListingServiceImpl) FetchOverviewAppsByEnvironment(envId, limit, offset int) (*OverviewAppsByEnvironmentBean, error) {
resp := &OverviewAppsByEnvironmentBean{}
env, err := impl.environmentRepository.FindById(envId)
Expand All @@ -220,11 +233,34 @@ func (impl AppListingServiceImpl) FetchOverviewAppsByEnvironment(envId, limit, o
resp.EnvironmentId = envId
resp.EnvironmentName = env.Name
resp.ClusterName = env.Cluster.ClusterName
resp.ClusterId = env.ClusterId
resp.Namespace = env.Namespace
resp.CreatedOn = env.CreatedOn.String()
if env.Default {
resp.Type = Production
} else {
resp.Type = NonProduction
}
resp.Description = env.Description
createdBy, err := impl.userRepository.GetById(env.CreatedBy)
if err != nil {
return resp, err
}
resp.CreatedBy = createdBy.EmailId
envContainers, err := impl.appListingRepository.FetchOverviewAppsByEnvironment(envId, limit, offset)
if err != nil {
return resp, err
}
for _, envContainer := range envContainers {
lastDeployed, err := impl.appListingRepository.FetchLastDeployedImage(envContainer.AppId, envId)
if err != nil {
return resp, err
}
if lastDeployed != nil {
envContainer.LastDeployedImage = lastDeployed.LastDeployedImage
envContainer.LastDeployedBy = lastDeployed.LastDeployedBy
}
}
resp.Apps = envContainers
return resp, err
}
Expand Down
Loading

0 comments on commit 649fede

Please sign in to comment.