Skip to content

feat: ext flux linking #6666

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 20 commits into
base: feat-flux-cd
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 3 additions & 1 deletion api/fluxApplication/FluxApplicationRestHandler.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ func (handler *FluxApplicationRestHandlerImpl) ListFluxApplications(w http.Respo
var clusterIds []int
var err error

noStream := v.Get("noStream") == "true"

//handling when the clusterIds string is empty ,it will not support the
if len(clusterIdString) == 0 {
handler.logger.Errorw("error in getting cluster ids", "error", err, "clusterIds", clusterIds)
Expand All @@ -57,7 +59,7 @@ func (handler *FluxApplicationRestHandlerImpl) ListFluxApplications(w http.Respo
return
}
handler.logger.Debugw("extracted ClusterIds successfully ", "clusterIds", clusterIds)
handler.fluxApplicationService.ListFluxApplications(r.Context(), clusterIds, w)
handler.fluxApplicationService.ListFluxApplications(r.Context(), clusterIds, noStream, w)
}

func (handler *FluxApplicationRestHandlerImpl) GetApplicationDetail(w http.ResponseWriter, r *http.Request) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2472,6 +2472,11 @@ func (handler *PipelineConfigRestHandlerImpl) ValidateExternalAppLinkRequest(w h
common.WriteJsonResp(w, err, response, http.StatusOK)
return
// handle helm deployment types
} else if request.DeploymentAppType == util.PIPELINE_DEPLOYMENT_TYPE_FLUX {
response := handler.pipelineBuilder.ValidateLinkFluxAppRequest(ctx, &request)
common.WriteJsonResp(w, err, response, http.StatusOK)
return
// handle helm deployment types
}
common.WriteJsonResp(w, errors.New("invalid deployment app type in request"), nil, http.StatusBadRequest)
return
Expand Down
2 changes: 1 addition & 1 deletion env_gen.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions env_gen.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
| RUN_HELM_INSTALL_IN_ASYNC_MODE_HELM_APPS | bool |false | | | false |
| SHOULD_CHECK_NAMESPACE_ON_CLONE | bool |false | should we check if namespace exists or not while cloning app | | false |
| USE_DEPLOYMENT_CONFIG_DATA | bool |false | use deployment config data from deployment_config table | | true |
| VALIDATE_EXT_APP_CHART_TYPE | bool |false | validate external flux app chart | | false |


## CI_RUNNER Related Environment Variables
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import (
type InstalledAppDBExtendedService interface {
EAMode.InstalledAppDBService
UpdateInstalledAppVersionStatus(application *v1alpha1.Application) (bool, error)
IsGitOpsRepoAlreadyRegistered(repoUrl string) (bool, error)
IsGitOpsRepoAlreadyRegistered(repoUrl string, appId int) (bool, error)
}

type InstalledAppDBExtendedServiceImpl struct {
Expand Down Expand Up @@ -91,9 +91,9 @@ func (impl *InstalledAppDBExtendedServiceImpl) UpdateInstalledAppVersionStatus(a
return true, nil
}

func (impl *InstalledAppDBExtendedServiceImpl) IsGitOpsRepoAlreadyRegistered(repoUrl string) (bool, error) {
func (impl *InstalledAppDBExtendedServiceImpl) IsGitOpsRepoAlreadyRegistered(repoUrl string, appId int) (bool, error) {

urlPresent, err := impl.InstalledAppDBServiceImpl.DeploymentConfigService.CheckIfURLAlreadyPresent(repoUrl)
urlPresent, err := impl.InstalledAppDBServiceImpl.DeploymentConfigService.CheckIfURLAlreadyPresent(repoUrl, appId)
if err != nil && !util.IsErrNoRows(err) {
impl.Logger.Errorw("error in checking url in deployment configs", "repoUrl", repoUrl, "err", err)
return false, err
Expand All @@ -111,6 +111,9 @@ func (impl *InstalledAppDBExtendedServiceImpl) IsGitOpsRepoAlreadyRegistered(rep
if util.IsErrNoRows(err) {
return false, nil
}
if installedAppModel != nil && installedAppModel.AppId == appId {
return false, nil
}
impl.Logger.Warnw("repository is already in use for helm app", "repoUrl", repoUrl, "appId", installedAppModel.AppId)
return true, nil
}
9 changes: 6 additions & 3 deletions pkg/chart/ChartService.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ type ChartService interface {
ConfigureGitOpsRepoUrlForApp(appId int, repoUrl, chartLocation string, isCustomRepo bool, userId int32) (*bean2.DeploymentConfig, error)

IsGitOpsRepoConfiguredForDevtronApp(appId int) (bool, error)
IsGitOpsRepoAlreadyRegistered(gitOpsRepoUrl string) (bool, error)
IsGitOpsRepoAlreadyRegistered(gitOpsRepoUrl string, appId int) (bool, error)

GetDeploymentTemplateDataByAppIdAndCharRefId(appId, chartRefId int) (map[string]interface{}, error)

Expand Down Expand Up @@ -1047,9 +1047,9 @@ func (impl *ChartServiceImpl) ConfigureGitOpsRepoUrlForApp(appId int, repoUrl, c
// return nil
//}

func (impl *ChartServiceImpl) IsGitOpsRepoAlreadyRegistered(gitOpsRepoUrl string) (bool, error) {
func (impl *ChartServiceImpl) IsGitOpsRepoAlreadyRegistered(gitOpsRepoUrl string, appId int) (bool, error) {

isURLPresent, err := impl.deploymentConfigService.CheckIfURLAlreadyPresent(gitOpsRepoUrl)
isURLPresent, err := impl.deploymentConfigService.CheckIfURLAlreadyPresent(gitOpsRepoUrl, appId)
if err != nil {
impl.logger.Errorw("error in checking if gitOps repo url is already present", "error", err)
return false, err
Expand All @@ -1065,6 +1065,9 @@ func (impl *ChartServiceImpl) IsGitOpsRepoAlreadyRegistered(gitOpsRepoUrl string
} else if util.IsErrNoRows(err) {
return false, nil
}
if chartModel != nil && chartModel.AppId == appId {
return false, nil
}
impl.logger.Errorw("repository is already in use for devtron app", "repoUrl", gitOpsRepoUrl, "appId", chartModel.AppId)
return true, nil
}
Expand Down
4 changes: 4 additions & 0 deletions pkg/commonService/CommonBaseService.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ func (impl *CommonBaseServiceImpl) isGitOpsEnable() (*FeatureGitOpsVariables, er
featureGitOpsFlags := &FeatureGitOpsVariables{
IsFeatureArgoCdMigrationEnabled: impl.globalEnvVariables.DeploymentServiceTypeConfig.IsFeatureMigrateArgoCdApplicationEnable(),
}
if impl.globalEnvVariables.DeploymentServiceTypeConfig.FeatureMigrateFluxApplicationEnable {
featureGitOpsFlags.IsFeatureGitOpsEnabled = true
featureGitOpsFlags.IsFeatureUserDefinedGitOpsEnabled = true
}
argoModule, err := impl.moduleReadService.GetModuleInfoByName(bean.ModuleNameArgoCd)
if err != nil && !errors.Is(err, moduleErr.ModuleNotFoundError) {
impl.logger.Errorw("error in getting argo module", "error", err)
Expand Down
7 changes: 4 additions & 3 deletions pkg/deployment/common/adapter/adapter.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,14 +73,14 @@ func NewAppLevelReleaseConfigFromChart(gitRepoURL, chartLocation string) *bean.R
}}
}

func NewFluxSpecReleaseConfig(clusterId int, namespace, gitRepositoryName, helmReleaseName, gitOpsSecretName, ChartLocation, ChartVersion,
RevisionTarget, RepoUrl string, DevtronValueFileName string, HelmReleaseValuesFiles []string) *bean.ReleaseConfiguration {
func NewFluxSpecReleaseConfig(clusterId int, helmReleaseNamespace, gitRepositoryName, gitRepositoryNamespace, helmReleaseName, gitOpsSecretName, ChartLocation, ChartVersion, RevisionTarget, RepoUrl, DevtronValueFileName string, HelmReleaseValuesFiles []string, extValues string) *bean.ReleaseConfiguration {
return &bean.ReleaseConfiguration{
Version: bean.Version,
FluxCDSpec: bean.FluxCDSpec{
ClusterId: clusterId,
Namespace: namespace,
HelmReleaseNamespace: helmReleaseNamespace,
GitRepositoryName: gitRepositoryName,
GitRepositoryNamespace: gitRepositoryNamespace,
HelmReleaseName: helmReleaseName,
GitOpsSecretName: gitOpsSecretName,
ChartLocation: ChartLocation,
Expand All @@ -89,6 +89,7 @@ func NewFluxSpecReleaseConfig(clusterId int, namespace, gitRepositoryName, helmR
RepoUrl: RepoUrl,
DevtronValueFile: DevtronValueFileName,
HelmReleaseValuesFiles: HelmReleaseValuesFiles,
ExtFluxValues: extValues,
}}
}

Expand Down
12 changes: 7 additions & 5 deletions pkg/deployment/common/bean/bean.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,20 @@ type ReleaseConfiguration struct {
}

type FluxCDSpec struct {
ClusterId int `json:"clusterId"`
Namespace string `json:"namespace"`
GitRepositoryName string `json:"gitRepositoryName"`
HelmReleaseName string `json:"helmReleaseName"`
GitOpsSecretName string `json:"gitOpsSecretName"` //fmt.Sprintf("devtron-flux-secret-%d", gitOpsConfig.Id)
ClusterId int `json:"clusterId"`
HelmReleaseNamespace string `json:"helmReleaseNamespace"`
GitRepositoryName string `json:"gitRepositoryName"`
GitRepositoryNamespace string `json:"gitRepositoryNamespace"`
HelmReleaseName string `json:"helmReleaseName"`
GitOpsSecretName string `json:"gitOpsSecretName"` //fmt.Sprintf("devtron-flux-secret-%d", gitOpsConfig.Id)

ChartLocation string `json:"chartLocation"`
ChartVersion string `json:"chartVersion"`
RevisionTarget string `json:"revisionTarget"`
RepoUrl string `json:"repoUrl"`
DevtronValueFile string `json:"devtronValueFile"`
HelmReleaseValuesFiles []string `json:"helmReleaseValuesFiles"` //getValuesFileArr
ExtFluxValues string `json:"extFluxValues"`
}

func (f *FluxCDSpec) GetFinalValuesFilePathArray() []string {
Expand Down
6 changes: 3 additions & 3 deletions pkg/deployment/common/deploymentConfigService.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ type DeploymentConfigService interface {
UpdateChartLocationInDeploymentConfig(appId, envId, chartRefId int, userId int32, chartVersion string) error
GetAllArgoAppInfosByDeploymentAppNames(deploymentAppNames []string) ([]*bean.DevtronArgoCdAppInfo, error)
GetExternalReleaseType(appId, environmentId int) (bean.ExternalReleaseType, error)
CheckIfURLAlreadyPresent(repoURL string) (bool, error)
CheckIfURLAlreadyPresent(repoURL string, appId int) (bool, error)
FilterPipelinesByApplicationClusterIdAndNamespace(pipelines []pipelineConfig.Pipeline, applicationObjectClusterId int, applicationObjectNamespace string) (pipelineConfig.Pipeline, error)
}

Expand Down Expand Up @@ -408,15 +408,15 @@ func (impl *DeploymentConfigServiceImpl) GetExternalReleaseType(appId, environme
return externalHelmReleaseType, nil
}

func (impl *DeploymentConfigServiceImpl) CheckIfURLAlreadyPresent(repoURL string) (bool, error) {
func (impl *DeploymentConfigServiceImpl) CheckIfURLAlreadyPresent(repoURL string, appId int) (bool, error) {
//TODO: optimisation
configs, err := impl.getAllAppLevelConfigsWithCustomGitOpsURL()
if err != nil {
impl.logger.Errorw("error in getting all configs", "err", err)
return false, err
}
for _, dc := range configs {
if dc.GetRepoURL() == repoURL {
if dc.GetRepoURL() == repoURL && dc.AppId != appId {
impl.logger.Warnw("repository is already in use for helm app", "repoUrl", repoURL)
return true, nil
}
Expand Down
1 change: 1 addition & 0 deletions pkg/deployment/gitOps/validation/bean/bean.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ type ValidateGitOpsRepoUrlRequest struct {
RequestedGitUrl string
DesiredGitUrl string
UseActiveGitOps bool
AppId int
}

type ValidateGitOpsRepoRequest struct {
Expand Down
8 changes: 4 additions & 4 deletions pkg/deployment/gitOps/validation/gitOpsValidationService.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ func (impl *GitOpsValidationServiceImpl) ValidateGitOpsRepoUrl(request *gitOpsBe
// Validate: Organisational URL ends

// Validate: Unique GitOps repository URL starts
isValid := impl.validateUniqueGitOpsRepo(sanitiseGitRepoUrl)
isValid := impl.validateUniqueGitOpsRepo(sanitiseGitRepoUrl, request.AppId)
if !isValid {
impl.logger.Errorw("git repo url already exists", "repo url", request.RequestedGitUrl)
errMsg := fmt.Sprintf("invalid git repository! '%s' is already in use by another application! Use a different repository", request.RequestedGitUrl)
Expand Down Expand Up @@ -350,12 +350,12 @@ func (impl *GitOpsValidationServiceImpl) getValidationErrorForNonOrganisationalU
WithCode(constants.GitOpsOrganisationMismatch)
}

func (impl *GitOpsValidationServiceImpl) validateUniqueGitOpsRepo(repoUrl string) (isValid bool) {
isDevtronAppRegistered, err := impl.chartService.IsGitOpsRepoAlreadyRegistered(repoUrl)
func (impl *GitOpsValidationServiceImpl) validateUniqueGitOpsRepo(repoUrl string, appId int) (isValid bool) {
isDevtronAppRegistered, err := impl.chartService.IsGitOpsRepoAlreadyRegistered(repoUrl, appId)
if err != nil || isDevtronAppRegistered {
return isValid
}
isHelmAppRegistered, err := impl.installedAppService.IsGitOpsRepoAlreadyRegistered(repoUrl)
isHelmAppRegistered, err := impl.installedAppService.IsGitOpsRepoAlreadyRegistered(repoUrl, appId)
if err != nil || isHelmAppRegistered {
return isValid
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ func (impl *HandlerServiceImpl) deployFluxCdApp(ctx context.Context, overrideReq
gitOpsSecret, err := impl.upsertGitRepoSecret(newCtx,
valuesOverrideResponse.DeploymentConfig.ReleaseConfiguration.FluxCDSpec.GitOpsSecretName,
valuesOverrideResponse.ManifestPushTemplate.RepoUrl,
overrideRequest.Namespace,
valuesOverrideResponse.DeploymentConfig.ReleaseConfiguration.FluxCDSpec.GitRepositoryNamespace,
clusterConfig)
if err != nil {
impl.logger.Errorw("error in creating git repo secret", "clusterId", overrideRequest.ClusterId, "err", err)
Expand Down Expand Up @@ -214,7 +214,7 @@ func (impl *HandlerServiceImpl) updateFluxCdApp(ctx context.Context, valuesOverr
}

func (impl *HandlerServiceImpl) CreateGitRepository(ctx context.Context, fluxCdSpec bean.FluxCDSpec, secretName string, manifestPushTemplate *bean2.ManifestPushTemplate, apiClient client.Client) (*sourcev1.GitRepository, error) {
name, namespace := fluxCdSpec.GitRepositoryName, fluxCdSpec.Namespace
name, namespace := fluxCdSpec.GitRepositoryName, fluxCdSpec.GitRepositoryNamespace
gitRepo := &sourcev1.GitRepository{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Expand All @@ -241,7 +241,7 @@ func (impl *HandlerServiceImpl) CreateGitRepository(ctx context.Context, fluxCdS

func (impl *HandlerServiceImpl) UpdateGitRepository(ctx context.Context, fluxCdSpec bean.FluxCDSpec, manifestPushTemplate *bean2.ManifestPushTemplate,
secretName string, apiClient client.Client) (*sourcev1.GitRepository, error) {
name, namespace := fluxCdSpec.GitRepositoryName, fluxCdSpec.Namespace
name, namespace := fluxCdSpec.GitRepositoryName, fluxCdSpec.GitRepositoryNamespace
key := types.NamespacedName{Name: name, Namespace: namespace}
existing := &sourcev1.GitRepository{}

Expand All @@ -265,7 +265,7 @@ func (impl *HandlerServiceImpl) UpdateGitRepository(ctx context.Context, fluxCdS

func (impl *HandlerServiceImpl) CreateHelmRelease(ctx context.Context, fluxCdSpec bean.FluxCDSpec,
manifestPushTemplate *bean2.ManifestPushTemplate, apiClient client.Client) (*helmv2.HelmRelease, error) {
name, namespace := fluxCdSpec.GitRepositoryName, fluxCdSpec.Namespace
name, namespace := fluxCdSpec.HelmReleaseName, fluxCdSpec.HelmReleaseNamespace
helmRelease := &helmv2.HelmRelease{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Expand All @@ -286,8 +286,8 @@ func (impl *HandlerServiceImpl) CreateHelmRelease(ctx context.Context, fluxCdSpe
Version: manifestPushTemplate.ChartVersion,
SourceRef: helmv2.CrossNamespaceObjectReference{
Kind: sourcev1.GitRepositoryKind,
Name: name, //using same name for git repository and helm release which will be = deploymentAppName
Namespace: namespace,
Name: fluxCdSpec.GitRepositoryName, //using same name for git repository and helm release which will be = deploymentAppName
Namespace: fluxCdSpec.GitRepositoryNamespace,
},
ValuesFiles: fluxCdSpec.GetFinalValuesFilePathArray(),
},
Expand All @@ -304,7 +304,7 @@ func (impl *HandlerServiceImpl) CreateHelmRelease(ctx context.Context, fluxCdSpe

func (impl *HandlerServiceImpl) UpdateHelmRelease(ctx context.Context, fluxCdSpec bean.FluxCDSpec,
manifestPushTemplate *bean2.ManifestPushTemplate, apiClient client.Client) (*helmv2.HelmRelease, error) {
name, namespace := fluxCdSpec.GitRepositoryName, fluxCdSpec.Namespace
name, namespace := fluxCdSpec.HelmReleaseName, fluxCdSpec.HelmReleaseNamespace
key := types.NamespacedName{Name: name, Namespace: namespace}
existing := &helmv2.HelmRelease{}

Expand All @@ -324,12 +324,15 @@ func (impl *HandlerServiceImpl) UpdateHelmRelease(ctx context.Context, fluxCdSpe
Version: manifestPushTemplate.ChartVersion,
SourceRef: helmv2.CrossNamespaceObjectReference{
Kind: sourcev1.GitRepositoryKind,
Name: name,
Namespace: namespace,
Name: fluxCdSpec.GitRepositoryName,
Namespace: fluxCdSpec.GitRepositoryNamespace,
},
ValuesFiles: fluxCdSpec.GetFinalValuesFilePathArray(),
},
}
// resetting original values so that values are derived only from existing.Spec.Chart.Spec.ValuesFiles
existing.Spec.Values = nil
existing.Spec.ValuesFrom = nil
err = apiClient.Update(ctx, existing)
if err != nil {
impl.logger.Errorw("error in updating helm release", "name", name, "namespace", namespace, "err", err)
Expand Down
Loading