diff --git a/internal/sql/repository/deploymentConfig/repository.go b/internal/sql/repository/deploymentConfig/repository.go index 45dad95627..b51286d2f1 100644 --- a/internal/sql/repository/deploymentConfig/repository.go +++ b/internal/sql/repository/deploymentConfig/repository.go @@ -17,6 +17,7 @@ package deploymentConfig import ( + "github.com/devtron-labs/devtron/internal/sql/repository/helper" "github.com/devtron-labs/devtron/pkg/sql" "github.com/go-pg/pg" "github.com/go-pg/pg/orm" @@ -63,6 +64,7 @@ type Repository interface { GetByAppIdAndEnvIdEvenIfInactive(appId, envId int) (*DeploymentConfig, error) UpdateRepoUrlByAppIdAndEnvId(repoUrl string, appId, envId int) error GetConfigByAppIds(appIds []int) ([]*DeploymentConfig, error) + GetDeploymentAppTypeForChartStoreAppByAppId(appId int) (string, error) } type RepositoryImpl struct { @@ -203,3 +205,16 @@ func (impl *RepositoryImpl) GetConfigByAppIds(appIds []int) ([]*DeploymentConfig Select() return results, err } + +func (impl *RepositoryImpl) GetDeploymentAppTypeForChartStoreAppByAppId(appId int) (string, error) { + result := &DeploymentConfig{} + err := impl.dbConnection.Model(result). + Join("inner join app a"). + JoinOn("deployment_config.app_id = a.id"). + Where("deployment_config.app_id = ? ", appId). + Where("deployment_config.active = ?", true). + Where("a.active = ?", true). + Where("a.app_type = ? ", helper.ChartStoreApp). + Select() + return result.DeploymentAppType, err +} diff --git a/pkg/app/AppCrudOperationService.go b/pkg/app/AppCrudOperationService.go index f52af89dbc..ff4399513a 100644 --- a/pkg/app/AppCrudOperationService.go +++ b/pkg/app/AppCrudOperationService.go @@ -463,22 +463,22 @@ func convertUrlToHttpsIfSshType(url string) string { } // getAppAndProjectForAppIdentifier, returns app db model for an app unique identifier or from display_name if both exists else it throws pg.ErrNoRows -func (impl AppCrudOperationServiceImpl) getAppAndProjectForAppIdentifier(appIdentifier *helmBean.AppIdentifier) (*appRepository.App, error) { +func (impl AppCrudOperationServiceImpl) getAppAndProjectForAppIdentifier(appIdentifier *helmBean.AppIdentifier) (*appRepository.App, bool, error) { app := &appRepository.App{} var err error appNameUniqueIdentifier := appIdentifier.GetUniqueAppNameIdentifier() app, err = impl.appRepository.FindAppAndProjectByAppName(appNameUniqueIdentifier) if err != nil && err != pg.ErrNoRows && err != pg.ErrMultiRows { impl.logger.Errorw("error in fetching app meta data by unique app identifier", "appNameUniqueIdentifier", appNameUniqueIdentifier, "err", err) - return app, err + return app, false, err } if err == pg.ErrMultiRows { validApp, err := impl.dbMigration.FixMultipleAppsForInstalledApp(appNameUniqueIdentifier) if err != nil { impl.logger.Errorw("error in fixing multiple installed app entries", "appName", appNameUniqueIdentifier, "err", err) - return app, err + return app, false, err } - return validApp, err + return validApp, false, err } if util.IsErrNoRows(err) { //find app by display name if not found by unique identifier @@ -487,16 +487,28 @@ func (impl AppCrudOperationServiceImpl) getAppAndProjectForAppIdentifier(appIden validApp, err := impl.dbMigration.FixMultipleAppsForInstalledApp(appNameUniqueIdentifier) if err != nil { impl.logger.Errorw("error in fixing multiple installed app entries", "appName", appNameUniqueIdentifier, "err", err) - return app, err + return app, false, err } - return validApp, err + return validApp, false, err } if err != nil { impl.logger.Errorw("error in fetching app meta data by display name", "displayName", appIdentifier.ReleaseName, "err", err) - return app, err + return app, false, err + } + // there can be a case when an app whose installed_app is deployed via argocd and same appName is also deployed externally + // via helm then we need to check if app model found is not deployed by argocd. + isManagedByArgocd, err := impl.installedAppDbService.IsChartStoreAppManagedByArgoCd(app.Id) + if err != nil { + impl.logger.Errorw("error in checking if installed app linked to this app is managed via argocd or not ", "appId", app.Id, "err", err) + return app, false, err + } + if isManagedByArgocd { + // if this helm app is managed by argocd then we don't want to process this req. any further. + return app, true, nil } } - return app, nil + + return app, false, nil } // updateAppNameToUniqueAppIdentifierInApp, migrates values of app_name col. in app table to unique identifier and also updates display_name with releaseName @@ -540,6 +552,7 @@ func (impl AppCrudOperationServiceImpl) GetHelmAppMetaInfo(appId string) (*bean. app := &appRepository.App{} var err error var displayName string + var isManagedByArgocd bool impl.logger.Info("request payload, appId", appId) if len(appIdSplitted) > 1 { appIdDecoded, err := client.DecodeExternalAppAppId(appId) @@ -547,11 +560,17 @@ func (impl AppCrudOperationServiceImpl) GetHelmAppMetaInfo(appId string) (*bean. impl.logger.Errorw("error in decoding app id for external app", "appId", appId, "err", err) return nil, err } - app, err = impl.getAppAndProjectForAppIdentifier(appIdDecoded) + app, isManagedByArgocd, err = impl.getAppAndProjectForAppIdentifier(appIdDecoded) if err != nil && !util.IsErrNoRows(err) { impl.logger.Errorw("GetHelmAppMetaInfo, error in getAppAndProjectForAppIdentifier for external apps", "appIdentifier", appIdDecoded, "err", err) return nil, err } + if isManagedByArgocd { + info := &bean.AppMetaInfoDto{ + AppName: appIdDecoded.ReleaseName, + } + return info, nil + } // if app.DisplayName is empty then that app_name is not yet migrated to app name unique identifier if app.Id > 0 && len(app.DisplayName) == 0 { appNameUniqueIdentifier := appIdDecoded.GetUniqueAppNameIdentifier() diff --git a/pkg/appStore/installedApp/read/InstalledAppReadEAService.go b/pkg/appStore/installedApp/read/InstalledAppReadEAService.go index 998854b7ee..88d8a2568e 100644 --- a/pkg/appStore/installedApp/read/InstalledAppReadEAService.go +++ b/pkg/appStore/installedApp/read/InstalledAppReadEAService.go @@ -1,6 +1,7 @@ package read import ( + "github.com/devtron-labs/devtron/internal/util" "github.com/devtron-labs/devtron/pkg/appStore/installedApp/read/adapter" "github.com/devtron-labs/devtron/pkg/appStore/installedApp/read/bean" "github.com/devtron-labs/devtron/pkg/appStore/installedApp/repository" @@ -32,6 +33,8 @@ type InstalledAppReadServiceEA interface { // Additional details like app store details are also fetched. // Refer bean.InstalledAppVersionWithAppStoreDetails for more details. GetInstalledAppVersionIncludingDeleted(installedAppVersionId int) (*bean.InstalledAppVersionWithAppStoreDetails, error) + // IsChartStoreAppManagedByArgoCd returns if a chart store app is deployed via argo-cd or not + IsChartStoreAppManagedByArgoCd(appId int) (bool, error) } type InstalledAppReadServiceEAImpl struct { @@ -97,3 +100,12 @@ func (impl *InstalledAppReadServiceEAImpl) GetInstalledAppVersionIncludingDelete } return adapter.GetInstalledAppVersionWithAppStoreDetails(installedAppVersionModel), nil } + +func (impl *InstalledAppReadServiceEAImpl) IsChartStoreAppManagedByArgoCd(appId int) (bool, error) { + installedAppModel, err := impl.installedAppRepository.GetInstalledAppsMinByAppId(appId) + if err != nil { + impl.logger.Errorw("error while fetching installed apps by app id", "appId", appId, "error", err) + return false, err + } + return util.IsAcdApp(installedAppModel.DeploymentAppType), nil +} diff --git a/pkg/appStore/installedApp/service/EAMode/InstalledAppDBService.go b/pkg/appStore/installedApp/service/EAMode/InstalledAppDBService.go index 621668ae55..1e3418bed3 100644 --- a/pkg/appStore/installedApp/service/EAMode/InstalledAppDBService.go +++ b/pkg/appStore/installedApp/service/EAMode/InstalledAppDBService.go @@ -69,6 +69,8 @@ type InstalledAppDBService interface { GetAppStoreApplicationVersionIdByInstalledAppVersionHistoryId(version int) (int, error) GetInstalledAppVersionHistoryByVersionId(id int) ([]*appStoreRepo.InstalledAppVersionHistory, error) UpdateDeploymentHistoryMessage(installedAppVersionHistoryId int, message string) error + + IsChartStoreAppManagedByArgoCd(appId int) (bool, error) } type InstalledAppDBServiceImpl struct { @@ -533,3 +535,7 @@ func (impl *InstalledAppDBServiceImpl) MarkInstalledAppVersionModelInActive(inst } return nil } + +func (impl *InstalledAppDBServiceImpl) IsChartStoreAppManagedByArgoCd(appId int) (bool, error) { + return impl.deploymentConfigService.IsChartStoreAppManagedByArgoCd(appId) +} diff --git a/pkg/deployment/common/deploymentConfigService.go b/pkg/deployment/common/deploymentConfigService.go index 2d4d5bd4fb..8ac8eaffaf 100644 --- a/pkg/deployment/common/deploymentConfigService.go +++ b/pkg/deployment/common/deploymentConfigService.go @@ -39,6 +39,7 @@ type DeploymentConfigService interface { GetConfigForDevtronApps(appId, envId int) (*bean.DeploymentConfig, error) GetAndMigrateConfigIfAbsentForDevtronApps(appId, envId int) (*bean.DeploymentConfig, error) GetConfigForHelmApps(appId, envId int) (*bean.DeploymentConfig, error) + IsChartStoreAppManagedByArgoCd(appId int) (bool, error) GetConfigEvenIfInactive(appId, envId int) (*bean.DeploymentConfig, error) GetAndMigrateConfigIfAbsentForHelmApp(appId, envId int) (*bean.DeploymentConfig, error) GetAppLevelConfigForDevtronApp(appId int) (*bean.DeploymentConfig, error) @@ -387,6 +388,17 @@ func (impl *DeploymentConfigServiceImpl) GetConfigForHelmApps(appId, envId int) return ConvertDeploymentConfigDbObjToDTO(helmDeploymentConfig), nil } +func (impl *DeploymentConfigServiceImpl) IsChartStoreAppManagedByArgoCd(appId int) (bool, error) { + deploymentAppType, err := impl.deploymentConfigRepository.GetDeploymentAppTypeForChartStoreAppByAppId(appId) + if err != nil && !util2.IsErrNoRows(err) { + impl.logger.Errorw("error in GetDeploymentAppTypeForChartStoreAppByAppId", "appId", appId, "err", err) + return false, err + } else if util2.IsErrNoRows(err) { + return impl.installedAppReadService.IsChartStoreAppManagedByArgoCd(appId) + } + return util2.IsAcdApp(deploymentAppType), nil +} + func (impl *DeploymentConfigServiceImpl) GetConfigEvenIfInactive(appId, envId int) (*bean.DeploymentConfig, error) { config, err := impl.deploymentConfigRepository.GetByAppIdAndEnvIdEvenIfInactive(appId, envId) if err != nil {