diff --git a/api/bean/GitOpsConfig.go b/api/bean/GitOpsConfig.go index 10463a8aad..4ff2d5bd92 100644 --- a/api/bean/GitOpsConfig.go +++ b/api/bean/GitOpsConfig.go @@ -12,5 +12,23 @@ type GitOpsConfigDto struct { AzureProjectName string `json:"azureProjectName"` BitBucketWorkspaceId string `json:"bitBucketWorkspaceId"` BitBucketProjectKey string `json:"bitBucketProjectKey"` - UserId int32 `json:"-"` + + GitRepoName string `json:"gitRepoName"` + UserEmailId string `json:"userEmailId"` + Description string `json:"description"` + UserId int32 `json:"-"` +} + +type GitRepoRequestDto struct { + Host string `json:"host"` + Provider string `json:"provider"` + GitRepoName string `json:"gitRepoName"` + Username string `json:"username"` + UserEmailId string `json:"userEmailId"` + Token string `json:"token"` + GitLabGroupId string `json:"gitLabGroupId"` + GitHubOrgId string `json:"gitHubOrgId"` + AzureProjectName string `json:"azureProjectName"` + BitBucketWorkspaceId string `json:"bitBucketWorkspaceId"` + BitBucketProjectKey string `json:"bitBucketProjectKey"` } diff --git a/internal/util/ChartService.go b/internal/util/ChartService.go index 6dcc19dcdd..c498042f90 100644 --- a/internal/util/ChartService.go +++ b/internal/util/ChartService.go @@ -23,11 +23,13 @@ import ( "fmt" repository3 "github.com/argoproj/argo-cd/v2/pkg/apiclient/repository" "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/devtron-labs/devtron/api/bean" repository4 "github.com/devtron-labs/devtron/client/argocdServer/repository" "github.com/devtron-labs/devtron/internal/sql/repository" appStoreBean "github.com/devtron-labs/devtron/pkg/appStore/bean" repository2 "github.com/devtron-labs/devtron/pkg/user/repository" "github.com/devtron-labs/devtron/util" + "github.com/go-pg/pg" "io/ioutil" "math/rand" "net/http" @@ -222,9 +224,25 @@ func (impl ChartTemplateServiceImpl) CreateGitRepositoryForApp(gitOpsRepoName, b space := regexp.MustCompile(`\s+`) gitOpsRepoName = space.ReplaceAllString(gitOpsRepoName, "-") + gitOpsConfigBitbucket, err := impl.gitOpsConfigRepository.GetGitOpsConfigByProvider(BITBUCKET_PROVIDER) + if err != nil { + if err == pg.ErrNoRows { + gitOpsConfigBitbucket.BitBucketWorkspaceId = "" + } else { + return nil, err + } + } //getting user name & emailId for commit author data userEmailId, userName := impl.GetUserEmailIdAndNameForGitOpsCommit(userId) - repoUrl, _, detailedError := impl.gitFactory.Client.CreateRepository(gitOpsRepoName, fmt.Sprintf("helm chart for "+gitOpsRepoName), userName, userEmailId) + gitRepoRequest := &bean.GitOpsConfigDto{ + GitRepoName: gitOpsRepoName, + Description: fmt.Sprintf("helm chart for " + gitOpsRepoName), + Username: userName, + UserEmailId: userEmailId, + BitBucketWorkspaceId: gitOpsConfigBitbucket.BitBucketWorkspaceId, + BitBucketProjectKey: gitOpsConfigBitbucket.BitBucketProjectKey, + } + repoUrl, _, detailedError := impl.gitFactory.Client.CreateRepository(gitRepoRequest) for _, err := range detailedError.StageErrorMap { if err != nil { impl.logger.Errorw("error in creating git project", "name", gitOpsRepoName, "err", err) @@ -487,9 +505,25 @@ func (impl ChartTemplateServiceImpl) createAndPushToGitChartProxy(appStoreName, gitOpsRepoName := impl.GetGitOpsRepoName(installAppVersionRequest.AppName) installAppVersionRequest.GitOpsRepoName = gitOpsRepoName } + gitOpsConfigBitbucket, err := impl.gitOpsConfigRepository.GetGitOpsConfigByProvider(BITBUCKET_PROVIDER) + if err != nil { + if err == pg.ErrNoRows { + gitOpsConfigBitbucket.BitBucketWorkspaceId = "" + } else { + return nil, err + } + } //getting user name & emailId for commit author data userEmailId, userName := impl.GetUserEmailIdAndNameForGitOpsCommit(installAppVersionRequest.UserId) - repoUrl, _, detailedError := impl.gitFactory.Client.CreateRepository(installAppVersionRequest.GitOpsRepoName, "helm chart for "+installAppVersionRequest.GitOpsRepoName, userName, userEmailId) + gitRepoRequest := &bean.GitOpsConfigDto{ + GitRepoName: installAppVersionRequest.GitOpsRepoName, + Description: "helm chart for " + installAppVersionRequest.GitOpsRepoName, + Username: userName, + UserEmailId: userEmailId, + BitBucketWorkspaceId: gitOpsConfigBitbucket.BitBucketWorkspaceId, + BitBucketProjectKey: gitOpsConfigBitbucket.BitBucketProjectKey, + } + repoUrl, _, detailedError := impl.gitFactory.Client.CreateRepository(gitRepoRequest) for _, err := range detailedError.StageErrorMap { if err != nil { impl.logger.Errorw("error in creating git project", "name", installAppVersionRequest.GitOpsRepoName, "err", err) @@ -641,7 +675,14 @@ func (impl ChartTemplateServiceImpl) GetByteArrayRefChart(chartMetaData *chart.M func (impl ChartTemplateServiceImpl) CreateReadmeInGitRepo(gitOpsRepoName string, userId int32) error { userEmailId, userName := impl.GetUserEmailIdAndNameForGitOpsCommit(userId) - _, err := impl.gitFactory.Client.CreateReadme(gitOpsRepoName, userName, userEmailId) + gitOpsConfig, err := impl.gitOpsConfigRepository.GetGitOpsConfigActive() + config := &bean.GitOpsConfigDto{ + Username: userName, + UserEmailId: userEmailId, + GitRepoName: gitOpsRepoName, + BitBucketWorkspaceId: gitOpsConfig.BitBucketWorkspaceId, + } + _, err = impl.gitFactory.Client.CreateReadme(config) if err != nil { return err } diff --git a/internal/util/GitService.go b/internal/util/GitService.go index 7255822d06..e04a3ddc24 100644 --- a/internal/util/GitService.go +++ b/internal/util/GitService.go @@ -51,11 +51,11 @@ const ( ) type GitClient interface { - CreateRepository(name, description, userName, userEmailId string) (url string, isNew bool, detailedErrorGitOpsConfigActions DetailedErrorGitOpsConfigActions) - CommitValues(config *ChartConfig) (commitHash string, commitTime time.Time, err error) - GetRepoUrl(projectName string) (repoUrl string, err error) - DeleteRepository(name string) error - CreateReadme(name, userName, userEmailId string) (string, error) + CreateRepository(config *bean2.GitOpsConfigDto) (url string, isNew bool, detailedErrorGitOpsConfigActions DetailedErrorGitOpsConfigActions) + CommitValues(config *ChartConfig, gitOpsConfig *bean2.GitOpsConfigDto) (commitHash string, commitTime time.Time, err error) + GetRepoUrl(config *bean2.GitOpsConfigDto) (repoUrl string, err error) + DeleteRepository(config *bean2.GitOpsConfigDto) error + CreateReadme(config *bean2.GitOpsConfigDto) (string, error) GetCommits(repoName, projectName string) ([]*GitCommitDto, error) } @@ -132,15 +132,17 @@ func (factory *GitFactory) GetGitLabGroupPath(gitOpsConfig *bean2.GitOpsConfigDt func (factory *GitFactory) NewClientForValidation(gitOpsConfig *bean2.GitOpsConfigDto) (GitClient, *GitServiceImpl, error) { cfg := &GitConfig{ - GitlabGroupId: gitOpsConfig.GitLabGroupId, - GitToken: gitOpsConfig.Token, - GitUserName: gitOpsConfig.Username, - GitWorkingDir: GIT_WORKING_DIR, - GithubOrganization: gitOpsConfig.GitHubOrgId, - GitProvider: gitOpsConfig.Provider, - GitHost: gitOpsConfig.Host, - AzureToken: gitOpsConfig.Token, - AzureProject: gitOpsConfig.AzureProjectName, + GitlabGroupId: gitOpsConfig.GitLabGroupId, + GitToken: gitOpsConfig.Token, + GitUserName: gitOpsConfig.Username, + GitWorkingDir: GIT_WORKING_DIR, + GithubOrganization: gitOpsConfig.GitHubOrgId, + GitProvider: gitOpsConfig.Provider, + GitHost: gitOpsConfig.Host, + AzureToken: gitOpsConfig.Token, + AzureProject: gitOpsConfig.AzureProjectName, + BitbucketWorkspaceId: gitOpsConfig.BitBucketWorkspaceId, + BitbucketProjectKey: gitOpsConfig.BitBucketProjectKey, } gitService := NewGitServiceImpl(cfg, logger, factory.gitCliUtil) //factory.gitService = gitService @@ -150,7 +152,7 @@ func (factory *GitFactory) NewClientForValidation(gitOpsConfig *bean2.GitOpsConf } //factory.Client = client - logger.Infow("client changed successfully") + logger.Infow("client changed successfully", "cfg", cfg) return client, gitService, nil } diff --git a/internal/util/GitServiceAzure.go b/internal/util/GitServiceAzure.go index 05c279465c..d47f4f8be4 100644 --- a/internal/util/GitServiceAzure.go +++ b/internal/util/GitServiceAzure.go @@ -3,8 +3,8 @@ package util import ( "context" "fmt" + bean2 "github.com/devtron-labs/devtron/api/bean" "github.com/devtron-labs/devtron/internal/sql/repository" - "github.com/go-pg/pg" "github.com/microsoft/azure-devops-go-api/azuredevops" "github.com/microsoft/azure-devops-go-api/azuredevops/git" "go.uber.org/zap" @@ -20,12 +20,12 @@ type GitAzureClient struct { gitOpsConfigRepository repository.GitOpsConfigRepository } -func (impl GitAzureClient) GetRepoUrl(repoName string) (repoUrl string, err error) { - url, exists, err := impl.repoExists(repoName, impl.project) +func (impl GitAzureClient) GetRepoUrl(config *bean2.GitOpsConfigDto) (repoUrl string, err error) { + url, exists, err := impl.repoExists(config.GitRepoName, impl.project) if err != nil { return "", err } else if !exists { - return "", fmt.Errorf("%s :repo not found", repoName) + return "", fmt.Errorf("%s :repo not found", config.GitRepoName) } else { return url, nil } @@ -49,35 +49,26 @@ func NewGitAzureClient(token string, host string, project string, logger *zap.Su gitOpsConfigRepository: gitOpsConfigRepository, }, err } -func (impl GitAzureClient) DeleteRepository(name string) error { - gitOpsConfigBitbucket, err := impl.gitOpsConfigRepository.GetGitOpsConfigByProvider(BITBUCKET_PROVIDER) - if err != nil { - if err == pg.ErrNoRows { - gitOpsConfigBitbucket.AzureProject = "" - } else { - impl.logger.Errorw("error in fetching gitOps bitbucket config", "err", err) - return err - } - } +func (impl GitAzureClient) DeleteRepository(config *bean2.GitOpsConfigDto) error { clientAzure := *impl.client gitRepository, err := clientAzure.GetRepository(context.Background(), git.GetRepositoryArgs{ - RepositoryId: &name, - Project: &gitOpsConfigBitbucket.AzureProject, + RepositoryId: &config.GitRepoName, + Project: &config.AzureProjectName, }) if err != nil || gitRepository == nil { - impl.logger.Errorw("error in fetching repo azure", "project", name, "err", err) + impl.logger.Errorw("error in fetching repo azure", "project", config.GitRepoName, "err", err) return err } err = clientAzure.DeleteRepository(context.Background(), git.DeleteRepositoryArgs{RepositoryId: gitRepository.Id, Project: &impl.project}) if err != nil { - impl.logger.Errorw("error in deleting repo azure", "project", name, "err", err) + impl.logger.Errorw("error in deleting repo azure", "project", config.GitRepoName, "err", err) } return err } -func (impl GitAzureClient) CreateRepository(name, description, userName, userEmailId string) (url string, isNew bool, detailedErrorGitOpsConfigActions DetailedErrorGitOpsConfigActions) { +func (impl GitAzureClient) CreateRepository(config *bean2.GitOpsConfigDto) (url string, isNew bool, detailedErrorGitOpsConfigActions DetailedErrorGitOpsConfigActions) { detailedErrorGitOpsConfigActions.StageErrorMap = make(map[string]error) ctx := context.Background() - url, repoExists, err := impl.repoExists(name, impl.project) + url, repoExists, err := impl.repoExists(config.GitRepoName, impl.project) if err != nil { impl.logger.Errorw("error in communication with azure", "err", err) detailedErrorGitOpsConfigActions.StageErrorMap[GetRepoUrlStage] = err @@ -88,7 +79,7 @@ func (impl GitAzureClient) CreateRepository(name, description, userName, userEma return url, false, detailedErrorGitOpsConfigActions } gitRepositoryCreateOptions := git.GitRepositoryCreateOptions{ - Name: &name, + Name: &config.GitRepoName, } clientAzure := *impl.client operationReference, err := clientAzure.CreateRepository(ctx, git.CreateRepositoryArgs{ @@ -96,65 +87,65 @@ func (impl GitAzureClient) CreateRepository(name, description, userName, userEma Project: &impl.project, }) if err != nil { - impl.logger.Errorw("error in creating repo azure", "project", name, "err", err) + impl.logger.Errorw("error in creating repo azure", "project", config.GitRepoName, "err", err) detailedErrorGitOpsConfigActions.StageErrorMap[CreateRepoStage] = err return "", true, detailedErrorGitOpsConfigActions } logger.Infow("repo created ", "r", operationReference.WebUrl) detailedErrorGitOpsConfigActions.SuccessfulStages = append(detailedErrorGitOpsConfigActions.SuccessfulStages, CreateRepoStage) - validated, err := impl.ensureProjectAvailabilityOnHttp(name) + validated, err := impl.ensureProjectAvailabilityOnHttp(config.GitRepoName) if err != nil { - impl.logger.Errorw("error in ensuring project availability azure", "project", name, "err", err) + impl.logger.Errorw("error in ensuring project availability azure", "project", config.GitRepoName, "err", err) detailedErrorGitOpsConfigActions.StageErrorMap[CloneHttpStage] = err return *operationReference.WebUrl, true, detailedErrorGitOpsConfigActions } if !validated { - detailedErrorGitOpsConfigActions.StageErrorMap[CloneHttpStage] = fmt.Errorf("unable to validate project:%s in given time", name) + detailedErrorGitOpsConfigActions.StageErrorMap[CloneHttpStage] = fmt.Errorf("unable to validate project:%s in given time", config.GitRepoName) return "", true, detailedErrorGitOpsConfigActions } detailedErrorGitOpsConfigActions.SuccessfulStages = append(detailedErrorGitOpsConfigActions.SuccessfulStages, CloneHttpStage) - _, err = impl.CreateReadme(name, userName, userEmailId) + _, err = impl.CreateReadme(config) if err != nil { - impl.logger.Errorw("error in creating readme azure", "project", name, "err", err) + impl.logger.Errorw("error in creating readme azure", "project", config.GitRepoName, "err", err) detailedErrorGitOpsConfigActions.StageErrorMap[CreateReadmeStage] = err return *operationReference.WebUrl, true, detailedErrorGitOpsConfigActions } detailedErrorGitOpsConfigActions.SuccessfulStages = append(detailedErrorGitOpsConfigActions.SuccessfulStages, CreateReadmeStage) - validated, err = impl.ensureProjectAvailabilityOnSsh(impl.project, name, *operationReference.WebUrl) + validated, err = impl.ensureProjectAvailabilityOnSsh(impl.project, config.GitRepoName, *operationReference.WebUrl) if err != nil { - impl.logger.Errorw("error in ensuring project availability azure", "project", name, "err", err) + impl.logger.Errorw("error in ensuring project availability azure", "project", config.GitRepoName, "err", err) detailedErrorGitOpsConfigActions.StageErrorMap[CloneSshStage] = err return *operationReference.WebUrl, true, detailedErrorGitOpsConfigActions } if !validated { - detailedErrorGitOpsConfigActions.StageErrorMap[CloneSshStage] = fmt.Errorf("unable to validate project:%s in given time", name) + detailedErrorGitOpsConfigActions.StageErrorMap[CloneSshStage] = fmt.Errorf("unable to validate project:%s in given time", config.GitRepoName) return "", true, detailedErrorGitOpsConfigActions } detailedErrorGitOpsConfigActions.SuccessfulStages = append(detailedErrorGitOpsConfigActions.SuccessfulStages, CloneSshStage) return *operationReference.WebUrl, true, detailedErrorGitOpsConfigActions } -func (impl GitAzureClient) CreateReadme(repoName, userName, userEmailId string) (string, error) { +func (impl GitAzureClient) CreateReadme(config *bean2.GitOpsConfigDto) (string, error) { cfg := &ChartConfig{ - ChartName: repoName, + ChartName: config.GitRepoName, ChartLocation: "", FileName: "README.md", FileContent: "@devtron", ReleaseMessage: "readme", - ChartRepoName: repoName, - UserName: userName, - UserEmailId: userEmailId, + ChartRepoName: config.GitRepoName, + UserName: config.Username, + UserEmailId: config.UserEmailId, } - hash, _, err := impl.CommitValues(cfg) + hash, _, err := impl.CommitValues(cfg, config) if err != nil { - impl.logger.Errorw("error in creating readme azure", "repo", repoName, "err", err) + impl.logger.Errorw("error in creating readme azure", "repo", config.GitRepoName, "err", err) } return hash, err } -func (impl GitAzureClient) CommitValues(config *ChartConfig) (commitHash string, commitTime time.Time, err error) { +func (impl GitAzureClient) CommitValues(config *ChartConfig, gitOpsConfig *bean2.GitOpsConfigDto) (commitHash string, commitTime time.Time, err error) { branch := "master" branchfull := "refs/heads/master" path := filepath.Join(config.ChartLocation, config.FileName) diff --git a/internal/util/GitServiceBitbucket.go b/internal/util/GitServiceBitbucket.go index d6a79543a1..8be8359c0e 100644 --- a/internal/util/GitServiceBitbucket.go +++ b/internal/util/GitServiceBitbucket.go @@ -2,6 +2,7 @@ package util import ( "fmt" + bean2 "github.com/devtron-labs/devtron/api/bean" "github.com/devtron-labs/devtron/internal/sql/repository" "github.com/go-pg/pg" "github.com/ktrysmt/go-bitbucket" @@ -39,47 +40,25 @@ func NewGitBitbucketClient(username, token, host string, logger *zap.SugaredLogg } } -func (impl GitBitbucketClient) DeleteRepository(name string) error { - gitOpsConfigBitbucket, err := impl.gitOpsConfigRepository.GetGitOpsConfigByProvider(BITBUCKET_PROVIDER) - if err != nil { - if err == pg.ErrNoRows { - gitOpsConfigBitbucket = &repository.GitOpsConfig{} - gitOpsConfigBitbucket.BitBucketWorkspaceId = "" - gitOpsConfigBitbucket.BitBucketProjectKey = "" - } else { - impl.logger.Errorw("error in fetching gitOps bitbucket config", "err", err) - return err - } - } +func (impl GitBitbucketClient) DeleteRepository(config *bean2.GitOpsConfigDto) error { repoOptions := &bitbucket.RepositoryOptions{ - Owner: gitOpsConfigBitbucket.BitBucketWorkspaceId, - RepoSlug: name, + Owner: config.BitBucketWorkspaceId, + RepoSlug: config.GitRepoName, IsPrivate: "true", - Project: gitOpsConfigBitbucket.BitBucketProjectKey, + Project: config.BitBucketProjectKey, } - _, err = impl.client.Repositories.Repository.Delete(repoOptions) + _, err := impl.client.Repositories.Repository.Delete(repoOptions) if err != nil { impl.logger.Errorw("error in deleting repo gitlab", "repoName", repoOptions.RepoSlug, "err", err) } return err } -func (impl GitBitbucketClient) GetRepoUrl(repoName string) (repoUrl string, err error) { - gitOpsConfigBitbucket, err := impl.gitOpsConfigRepository.GetGitOpsConfigByProvider(BITBUCKET_PROVIDER) - if err != nil { - if err == pg.ErrNoRows { - gitOpsConfigBitbucket = &repository.GitOpsConfig{} - gitOpsConfigBitbucket.BitBucketWorkspaceId = "" - gitOpsConfigBitbucket.BitBucketProjectKey = "" - } else { - impl.logger.Errorw("error in fetching gitOps bitbucket config", "err", err) - return "", err - } - } +func (impl GitBitbucketClient) GetRepoUrl(config *bean2.GitOpsConfigDto) (repoUrl string, err error) { repoOptions := &bitbucket.RepositoryOptions{ - Owner: gitOpsConfigBitbucket.BitBucketWorkspaceId, - Project: gitOpsConfigBitbucket.BitBucketProjectKey, - RepoSlug: repoName, + Owner: config.BitBucketWorkspaceId, + Project: config.BitBucketProjectKey, + RepoSlug: config.GitRepoName, } _, exists, err := impl.repoExists(repoOptions) if err != nil { @@ -91,33 +70,22 @@ func (impl GitBitbucketClient) GetRepoUrl(repoName string) (repoUrl string, err return repoUrl, nil } } -func (impl GitBitbucketClient) CreateRepository(name, description, userName, userEmailId string) (url string, isNew bool, detailedErrorGitOpsConfigActions DetailedErrorGitOpsConfigActions) { +func (impl GitBitbucketClient) CreateRepository(config *bean2.GitOpsConfigDto) (url string, isNew bool, detailedErrorGitOpsConfigActions DetailedErrorGitOpsConfigActions) { detailedErrorGitOpsConfigActions.StageErrorMap = make(map[string]error) - gitOpsConfigBitbucket, err := impl.gitOpsConfigRepository.GetGitOpsConfigByProvider(BITBUCKET_PROVIDER) - if err != nil { - if err == pg.ErrNoRows { - gitOpsConfigBitbucket = &repository.GitOpsConfig{} - gitOpsConfigBitbucket.BitBucketWorkspaceId = "" - gitOpsConfigBitbucket.BitBucketProjectKey = "" - } else { - impl.logger.Errorw("error in fetching gitOps bitbucket config", "err", err) - return "", false, detailedErrorGitOpsConfigActions - } - } - workSpaceId := gitOpsConfigBitbucket.BitBucketWorkspaceId - projectKey := gitOpsConfigBitbucket.BitBucketProjectKey + workSpaceId := config.BitBucketWorkspaceId + projectKey := config.BitBucketProjectKey repoOptions := &bitbucket.RepositoryOptions{ Owner: workSpaceId, - RepoSlug: name, + RepoSlug: config.GitRepoName, Scm: "git", IsPrivate: "true", - Description: description, + Description: config.Description, Project: projectKey, } repoUrl, repoExists, err := impl.repoExists(repoOptions) if err != nil { - impl.logger.Errorw("error in communication with bitbucket", "err", err) + impl.logger.Errorw("error in communication with bitbucket", "repoOptions", repoOptions, "err", err) detailedErrorGitOpsConfigActions.StageErrorMap[GetRepoUrlStage] = err return "", false, detailedErrorGitOpsConfigActions } @@ -127,7 +95,7 @@ func (impl GitBitbucketClient) CreateRepository(name, description, userName, use } _, err = impl.client.Repositories.Repository.Create(repoOptions) if err != nil { - impl.logger.Errorw("error in creating repo bitbucket", "project", name, "err", err) + impl.logger.Errorw("error in creating repo bitbucket", "repoOptions", repoOptions, "err", err) detailedErrorGitOpsConfigActions.StageErrorMap[CreateRepoStage] = err return "", true, detailedErrorGitOpsConfigActions } @@ -142,12 +110,12 @@ func (impl GitBitbucketClient) CreateRepository(name, description, userName, use return "", true, detailedErrorGitOpsConfigActions } if !validated { - detailedErrorGitOpsConfigActions.StageErrorMap[CloneHttpStage] = fmt.Errorf("unable to validate project:%s in given time", name) + detailedErrorGitOpsConfigActions.StageErrorMap[CloneHttpStage] = fmt.Errorf("unable to validate project:%s in given time", config.GitRepoName) return "", true, detailedErrorGitOpsConfigActions } detailedErrorGitOpsConfigActions.SuccessfulStages = append(detailedErrorGitOpsConfigActions.SuccessfulStages, CloneHttpStage) - _, err = impl.CreateReadme(repoOptions.RepoSlug, userName, userEmailId) + _, err = impl.CreateReadme(config) if err != nil { impl.logger.Errorw("error in creating readme bitbucket", "repoName", repoOptions.RepoSlug, "err", err) detailedErrorGitOpsConfigActions.StageErrorMap[CreateReadmeStage] = err @@ -157,12 +125,12 @@ func (impl GitBitbucketClient) CreateRepository(name, description, userName, use validated, err = impl.ensureProjectAvailabilityOnSsh(repoOptions) if err != nil { - impl.logger.Errorw("error in ensuring project availability bitbucket", "project", name, "err", err) + impl.logger.Errorw("error in ensuring project availability bitbucket", "project", config.GitRepoName, "err", err) detailedErrorGitOpsConfigActions.StageErrorMap[CloneSshStage] = err return "", true, detailedErrorGitOpsConfigActions } if !validated { - detailedErrorGitOpsConfigActions.StageErrorMap[CloneSshStage] = fmt.Errorf("unable to validate project:%s in given time", name) + detailedErrorGitOpsConfigActions.StageErrorMap[CloneSshStage] = fmt.Errorf("unable to validate project:%s in given time", config.GitRepoName) return "", true, detailedErrorGitOpsConfigActions } detailedErrorGitOpsConfigActions.SuccessfulStages = append(detailedErrorGitOpsConfigActions.SuccessfulStages, CloneSshStage) @@ -196,23 +164,25 @@ func (impl GitBitbucketClient) ensureProjectAvailabilityOnHttp(repoOptions *bitb } return false, nil } -func (impl GitBitbucketClient) CreateReadme(repoName, userName, userEmailId string) (string, error) { + +func (impl GitBitbucketClient) CreateReadme(config *bean2.GitOpsConfigDto) (string, error) { cfg := &ChartConfig{ - ChartName: repoName, + ChartName: config.GitRepoName, ChartLocation: "", FileName: "README.md", FileContent: "@devtron", ReleaseMessage: "pushing readme", - ChartRepoName: repoName, - UserName: userName, - UserEmailId: userEmailId, + ChartRepoName: config.GitRepoName, + UserName: config.Username, + UserEmailId: config.UserEmailId, } - hash, _, err := impl.CommitValues(cfg) + hash, _, err := impl.CommitValues(cfg, config) if err != nil { - impl.logger.Errorw("error in creating readme bitbucket", "repo", repoName, "err", err) + impl.logger.Errorw("error in creating readme bitbucket", "repo", config.GitRepoName, "err", err) } return hash, err } + func (impl GitBitbucketClient) ensureProjectAvailabilityOnSsh(repoOptions *bitbucket.RepositoryOptions) (bool, error) { repoUrl := fmt.Sprintf(BITBUCKET_CLONE_BASE_URL+"%s/%s.git", repoOptions.Owner, repoOptions.RepoSlug) for count := 0; count < 5; count++ { @@ -227,19 +197,8 @@ func (impl GitBitbucketClient) ensureProjectAvailabilityOnSsh(repoOptions *bitbu return false, nil } -func (impl GitBitbucketClient) CommitValues(config *ChartConfig) (commitHash string, commitTime time.Time, err error) { - gitOpsConfigBitbucket, err := impl.gitOpsConfigRepository.GetGitOpsConfigByProvider(BITBUCKET_PROVIDER) - if err != nil { - if err == pg.ErrNoRows { - gitOpsConfigBitbucket = &repository.GitOpsConfig{} - gitOpsConfigBitbucket.BitBucketWorkspaceId = "" - gitOpsConfigBitbucket.BitBucketProjectKey = "" - } else { - impl.logger.Errorw("error in fetching gitOps bitbucket config", "err", err) - return "", time.Time{}, err - } - } - bitbucketWorkspaceId := gitOpsConfigBitbucket.BitBucketWorkspaceId +func (impl GitBitbucketClient) CommitValues(config *ChartConfig, gitOpsConfig *bean2.GitOpsConfigDto) (commitHash string, commitTime time.Time, err error) { + homeDir, err := os.UserHomeDir() if err != nil { return "", time.Time{}, err @@ -264,7 +223,7 @@ func (impl GitBitbucketClient) CommitValues(config *ChartConfig) (commitHash str //bitbucket needs author as - "Name " authorBitbucket := fmt.Sprintf("%s <%s>", config.UserName, config.UserEmailId) repoWriteOptions := &bitbucket.RepositoryBlobWriteOptions{ - Owner: bitbucketWorkspaceId, + Owner: gitOpsConfig.BitBucketWorkspaceId, RepoSlug: config.ChartRepoName, FilePath: bitbucketCommitFilePath, FileName: fileName, @@ -279,7 +238,7 @@ func (impl GitBitbucketClient) CommitValues(config *ChartConfig) (commitHash str } commitOptions := &bitbucket.CommitsOptions{ RepoSlug: config.ChartRepoName, - Owner: bitbucketWorkspaceId, + Owner: gitOpsConfig.BitBucketWorkspaceId, Branchortag: "master", } commits, err := impl.client.Repositories.Commits.GetCommits(commitOptions) diff --git a/internal/util/GitServiceGithub.go b/internal/util/GitServiceGithub.go index b3b2c8f1d2..12efedebc3 100644 --- a/internal/util/GitServiceGithub.go +++ b/internal/util/GitServiceGithub.go @@ -3,8 +3,8 @@ package util import ( "context" "fmt" + bean2 "github.com/devtron-labs/devtron/api/bean" "github.com/devtron-labs/devtron/internal/sql/repository" - "github.com/go-pg/pg" "github.com/google/go-github/github" "go.uber.org/zap" "golang.org/x/oauth2" @@ -59,28 +59,19 @@ func NewGithubClient(host string, token string, org string, logger *zap.SugaredL gitOpsConfigRepository: gitOpsConfigRepository, }, err } -func (impl GitHubClient) DeleteRepository(name string) error { - gitOpsConfig, err := impl.gitOpsConfigRepository.GetGitOpsConfigByProvider(GITHUB_PROVIDER) +func (impl GitHubClient) DeleteRepository(config *bean2.GitOpsConfigDto) error { + _, err := impl.client.Repositories.Delete(context.Background(), config.GitHubOrgId, config.GitRepoName) if err != nil { - if err == pg.ErrNoRows { - gitOpsConfig.GitHubOrgId = "" - } else { - impl.logger.Errorw("error in fetching gitOps github config", "err", err) - return err - } - } - _, err = impl.client.Repositories.Delete(context.Background(), gitOpsConfig.GitHubOrgId, name) - if err != nil { - impl.logger.Errorw("repo deletion failed for github", "repo", name, "err", err) + impl.logger.Errorw("repo deletion failed for github", "repo", config.GitRepoName, "err", err) return err } return nil } -func (impl GitHubClient) CreateRepository(name, description, userName, userEmailId string) (url string, isNew bool, detailedErrorGitOpsConfigActions DetailedErrorGitOpsConfigActions) { +func (impl GitHubClient) CreateRepository(config *bean2.GitOpsConfigDto) (url string, isNew bool, detailedErrorGitOpsConfigActions DetailedErrorGitOpsConfigActions) { detailedErrorGitOpsConfigActions.StageErrorMap = make(map[string]error) ctx := context.Background() repoExists := true - url, err := impl.GetRepoUrl(name) + url, err := impl.GetRepoUrl(config) if err != nil { responseErr, ok := err.(*github.ErrorResponse) if !ok || responseErr.Response.StatusCode != 404 { @@ -98,47 +89,47 @@ func (impl GitHubClient) CreateRepository(name, description, userName, userEmail private := true // visibility := "private" r, _, err := impl.client.Repositories.Create(ctx, impl.org, - &github.Repository{Name: &name, - Description: &description, + &github.Repository{Name: &config.GitRepoName, + Description: &config.Description, Private: &private, // Visibility: &visibility, }) if err != nil { - impl.logger.Errorw("error in creating github repo, ", "repo", name, "err", err) + impl.logger.Errorw("error in creating github repo, ", "repo", config.GitRepoName, "err", err) detailedErrorGitOpsConfigActions.StageErrorMap[CreateRepoStage] = err return "", true, detailedErrorGitOpsConfigActions } logger.Infow("github repo created ", "r", r.CloneURL) detailedErrorGitOpsConfigActions.SuccessfulStages = append(detailedErrorGitOpsConfigActions.SuccessfulStages, CreateRepoStage) - validated, err := impl.ensureProjectAvailabilityOnHttp(name) + validated, err := impl.ensureProjectAvailabilityOnHttp(config) if err != nil { - impl.logger.Errorw("error in ensuring project availability github", "project", name, "err", err) + impl.logger.Errorw("error in ensuring project availability github", "project", config.GitRepoName, "err", err) detailedErrorGitOpsConfigActions.StageErrorMap[CloneHttpStage] = err return *r.CloneURL, true, detailedErrorGitOpsConfigActions } if !validated { - detailedErrorGitOpsConfigActions.StageErrorMap[CloneHttpStage] = fmt.Errorf("unable to validate project:%s in given time", name) + detailedErrorGitOpsConfigActions.StageErrorMap[CloneHttpStage] = fmt.Errorf("unable to validate project:%s in given time", config.GitRepoName) return "", true, detailedErrorGitOpsConfigActions } detailedErrorGitOpsConfigActions.SuccessfulStages = append(detailedErrorGitOpsConfigActions.SuccessfulStages, CloneHttpStage) - _, err = impl.CreateReadme(name, userName, userEmailId) + _, err = impl.CreateReadme(config) if err != nil { - impl.logger.Errorw("error in creating readme github", "project", name, "err", err) + impl.logger.Errorw("error in creating readme github", "project", config.GitRepoName, "err", err) detailedErrorGitOpsConfigActions.StageErrorMap[CreateReadmeStage] = err return *r.CloneURL, true, detailedErrorGitOpsConfigActions } detailedErrorGitOpsConfigActions.SuccessfulStages = append(detailedErrorGitOpsConfigActions.SuccessfulStages, CreateReadmeStage) - validated, err = impl.ensureProjectAvailabilityOnSsh(name, *r.CloneURL) + validated, err = impl.ensureProjectAvailabilityOnSsh(config.GitRepoName, *r.CloneURL) if err != nil { - impl.logger.Errorw("error in ensuring project availability github", "project", name, "err", err) + impl.logger.Errorw("error in ensuring project availability github", "project", config.GitRepoName, "err", err) detailedErrorGitOpsConfigActions.StageErrorMap[CloneSshStage] = err return *r.CloneURL, true, detailedErrorGitOpsConfigActions } if !validated { - detailedErrorGitOpsConfigActions.StageErrorMap[CloneSshStage] = fmt.Errorf("unable to validate project:%s in given time", name) + detailedErrorGitOpsConfigActions.StageErrorMap[CloneSshStage] = fmt.Errorf("unable to validate project:%s in given time", config.GitRepoName) return "", true, detailedErrorGitOpsConfigActions } detailedErrorGitOpsConfigActions.SuccessfulStages = append(detailedErrorGitOpsConfigActions.SuccessfulStages, CloneSshStage) @@ -146,25 +137,25 @@ func (impl GitHubClient) CreateRepository(name, description, userName, userEmail return *r.CloneURL, true, detailedErrorGitOpsConfigActions } -func (impl GitHubClient) CreateReadme(repoName, userName, userEmailId string) (string, error) { +func (impl GitHubClient) CreateReadme(config *bean2.GitOpsConfigDto) (string, error) { cfg := &ChartConfig{ - ChartName: repoName, + ChartName: config.GitRepoName, ChartLocation: "", FileName: "README.md", FileContent: "@devtron", ReleaseMessage: "readme", - ChartRepoName: repoName, - UserName: userName, - UserEmailId: userEmailId, + ChartRepoName: config.GitRepoName, + UserName: config.Username, + UserEmailId: config.UserEmailId, } - hash, _, err := impl.CommitValues(cfg) + hash, _, err := impl.CommitValues(cfg, config) if err != nil { - impl.logger.Errorw("error in creating readme github", "repo", repoName, "err", err) + impl.logger.Errorw("error in creating readme github", "repo", config.GitRepoName, "err", err) } return hash, err } -func (impl GitHubClient) CommitValues(config *ChartConfig) (commitHash string, commitTime time.Time, err error) { +func (impl GitHubClient) CommitValues(config *ChartConfig, gitOpsConfig *bean2.GitOpsConfigDto) (commitHash string, commitTime time.Time, err error) { branch := "master" path := filepath.Join(config.ChartLocation, config.FileName) ctx := context.Background() @@ -208,29 +199,29 @@ func (impl GitHubClient) CommitValues(config *ChartConfig) (commitHash string, c return *c.SHA, *c.Commit.Author.Date, nil } -func (impl GitHubClient) GetRepoUrl(projectName string) (repoUrl string, err error) { +func (impl GitHubClient) GetRepoUrl(config *bean2.GitOpsConfigDto) (repoUrl string, err error) { ctx := context.Background() - repo, _, err := impl.client.Repositories.Get(ctx, impl.org, projectName) + repo, _, err := impl.client.Repositories.Get(ctx, impl.org, config.GitRepoName) if err != nil { return "", err } return *repo.CloneURL, nil } -func (impl GitHubClient) ensureProjectAvailabilityOnHttp(projectName string) (bool, error) { +func (impl GitHubClient) ensureProjectAvailabilityOnHttp(config *bean2.GitOpsConfigDto) (bool, error) { count := 0 for count < 3 { count = count + 1 - _, err := impl.GetRepoUrl(projectName) + _, err := impl.GetRepoUrl(config) if err == nil { return true, nil } responseErr, ok := err.(*github.ErrorResponse) if !ok || responseErr.Response.StatusCode != 404 { - impl.logger.Errorw("error in validating repo github", "project", projectName, "err", err) + impl.logger.Errorw("error in validating repo github", "project", config.GitRepoName, "err", err) return false, err } else { - impl.logger.Errorw("error in validating repo github", "project", projectName, "err", err) + impl.logger.Errorw("error in validating repo github", "project", config.GitRepoName, "err", err) } time.Sleep(10 * time.Second) } diff --git a/internal/util/GitServiceGitlab.go b/internal/util/GitServiceGitlab.go index 483059c4f9..ad34974412 100644 --- a/internal/util/GitServiceGitlab.go +++ b/internal/util/GitServiceGitlab.go @@ -2,6 +2,7 @@ package util import ( "fmt" + bean2 "github.com/devtron-labs/devtron/api/bean" "github.com/xanzy/go-gitlab" "go.uber.org/zap" "net/url" @@ -81,19 +82,20 @@ func NewGitLabClient(config *GitConfig, logger *zap.SugaredLogger, gitService Gi }, nil } -func (impl GitLabClient) DeleteRepository(name string) error { - err := impl.DeleteProject(name) +func (impl GitLabClient) DeleteRepository(config *bean2.GitOpsConfigDto) error { + err := impl.DeleteProject(config.GitRepoName) if err != nil { - impl.logger.Errorw("error in deleting repo gitlab", "project", name, "err", err) + impl.logger.Errorw("error in deleting repo gitlab", "project", config.GitRepoName, "err", err) } return err } -func (impl GitLabClient) CreateRepository(name, description, userName, userEmailId string) (url string, isNew bool, detailedErrorGitOpsConfigActions DetailedErrorGitOpsConfigActions) { + +func (impl GitLabClient) CreateRepository(config *bean2.GitOpsConfigDto) (url string, isNew bool, detailedErrorGitOpsConfigActions DetailedErrorGitOpsConfigActions) { detailedErrorGitOpsConfigActions.StageErrorMap = make(map[string]error) - impl.logger.Debugw("gitlab app create request ", "name", name, "description", description) - repoUrl, err := impl.GetRepoUrl(name) + impl.logger.Debugw("gitlab app create request ", "name", config.GitRepoName, "description", config.Description) + repoUrl, err := impl.GetRepoUrl(config) if err != nil { - impl.logger.Errorw("error in getting repo url ", "gitlab project", name, "err", err) + impl.logger.Errorw("error in getting repo url ", "gitlab project", config.GitRepoName, "err", err) detailedErrorGitOpsConfigActions.StageErrorMap[GetRepoUrlStage] = err return "", false, detailedErrorGitOpsConfigActions } @@ -101,7 +103,7 @@ func (impl GitLabClient) CreateRepository(name, description, userName, userEmail detailedErrorGitOpsConfigActions.SuccessfulStages = append(detailedErrorGitOpsConfigActions.SuccessfulStages, GetRepoUrlStage) return repoUrl, false, detailedErrorGitOpsConfigActions } else { - url, err = impl.createProject(name, description) + url, err = impl.createProject(config.GitRepoName, config.Description) if err != nil { detailedErrorGitOpsConfigActions.StageErrorMap[CreateRepoStage] = err return "", true, detailedErrorGitOpsConfigActions @@ -109,32 +111,32 @@ func (impl GitLabClient) CreateRepository(name, description, userName, userEmail detailedErrorGitOpsConfigActions.SuccessfulStages = append(detailedErrorGitOpsConfigActions.SuccessfulStages, CreateRepoStage) } repoUrl = url - validated, err := impl.ensureProjectAvailability(name) + validated, err := impl.ensureProjectAvailability(config.GitRepoName) if err != nil { - impl.logger.Errorw("error in ensuring project availability ", "gitlab project", name, "err", err) + impl.logger.Errorw("error in ensuring project availability ", "gitlab project", config.GitRepoName, "err", err) detailedErrorGitOpsConfigActions.StageErrorMap[CloneHttpStage] = err return "", true, detailedErrorGitOpsConfigActions } if !validated { - detailedErrorGitOpsConfigActions.StageErrorMap[CloneHttpStage] = fmt.Errorf("unable to validate project:%s in given time", name) + detailedErrorGitOpsConfigActions.StageErrorMap[CloneHttpStage] = fmt.Errorf("unable to validate project:%s in given time", config.GitRepoName) return "", true, detailedErrorGitOpsConfigActions } detailedErrorGitOpsConfigActions.SuccessfulStages = append(detailedErrorGitOpsConfigActions.SuccessfulStages, CloneHttpStage) - _, err = impl.CreateReadme(fmt.Sprintf("%s/%s", impl.config.GitlabGroupPath, name), userName, userEmailId) + _, err = impl.CreateReadme(config) if err != nil { - impl.logger.Errorw("error in creating readme ", "gitlab project", name, "err", err) + impl.logger.Errorw("error in creating readme ", "gitlab project", config.GitRepoName, "err", err) detailedErrorGitOpsConfigActions.StageErrorMap[CreateReadmeStage] = err return "", true, detailedErrorGitOpsConfigActions } detailedErrorGitOpsConfigActions.SuccessfulStages = append(detailedErrorGitOpsConfigActions.SuccessfulStages, CreateReadmeStage) - validated, err = impl.ensureProjectAvailabilityOnSsh(name, repoUrl) + validated, err = impl.ensureProjectAvailabilityOnSsh(config.GitRepoName, repoUrl) if err != nil { - impl.logger.Errorw("error in ensuring project availability ", "gitlab project", name, "err", err) + impl.logger.Errorw("error in ensuring project availability ", "gitlab project", config.GitRepoName, "err", err) detailedErrorGitOpsConfigActions.StageErrorMap[CloneSshStage] = err return "", true, detailedErrorGitOpsConfigActions } if !validated { - detailedErrorGitOpsConfigActions.StageErrorMap[CloneSshStage] = fmt.Errorf("unable to validate project:%s in given time", name) + detailedErrorGitOpsConfigActions.StageErrorMap[CloneSshStage] = fmt.Errorf("unable to validate project:%s in given time", config.GitRepoName) return "", true, detailedErrorGitOpsConfigActions } detailedErrorGitOpsConfigActions.SuccessfulStages = append(detailedErrorGitOpsConfigActions.SuccessfulStages, CloneSshStage) @@ -207,8 +209,8 @@ func (impl GitLabClient) ensureProjectAvailabilityOnSsh(projectName string, repo return false, nil } -func (impl GitLabClient) GetRepoUrl(projectName string) (repoUrl string, err error) { - pid := fmt.Sprintf("%s/%s", impl.config.GitlabGroupPath, projectName) +func (impl GitLabClient) GetRepoUrl(config *bean2.GitOpsConfigDto) (repoUrl string, err error) { + pid := fmt.Sprintf("%s/%s", impl.config.GitlabGroupPath, config.GitRepoName) prop, res, err := impl.client.Projects.GetProject(pid, &gitlab.GetProjectOptions{}) if err != nil { impl.logger.Debugw("gitlab get project err", "pid", pid, "err", err) @@ -223,7 +225,7 @@ func (impl GitLabClient) GetRepoUrl(projectName string) (repoUrl string, err err return "", nil } -func (impl GitLabClient) CreateReadme(name, userName, userEmailId string) (string, error) { +func (impl GitLabClient) CreateReadme(config *bean2.GitOpsConfigDto) (string, error) { fileAction := gitlab.FileCreate filePath := "README.md" fileContent := "devtron licence" @@ -231,18 +233,20 @@ func (impl GitLabClient) CreateReadme(name, userName, userEmailId string) (strin Branch: gitlab.String("master"), CommitMessage: gitlab.String("test commit"), Actions: []*gitlab.CommitActionOptions{{Action: &fileAction, FilePath: &filePath, Content: &fileContent}}, - AuthorEmail: &userEmailId, - AuthorName: &userName, + AuthorEmail: &config.UserEmailId, + AuthorName: &config.Username, } - c, _, err := impl.client.Commits.CreateCommit(name, actions) + gitRepoName := fmt.Sprintf("%s/%s", impl.config.GitlabGroupPath, config.GitRepoName) + c, _, err := impl.client.Commits.CreateCommit(gitRepoName, actions) return c.ID, err } + func (impl GitLabClient) checkIfFileExists(projectName, ref, file string) (exists bool, err error) { _, _, err = impl.client.RepositoryFiles.GetFileMetaData(fmt.Sprintf("%s/%s", impl.config.GitlabGroupPath, projectName), file, &gitlab.GetFileMetaDataOptions{Ref: &ref}) return err == nil, err } -func (impl GitLabClient) CommitValues(config *ChartConfig) (commitHash string, commitTime time.Time, err error) { +func (impl GitLabClient) CommitValues(config *ChartConfig, gitOpsConfig *bean2.GitOpsConfigDto) (commitHash string, commitTime time.Time, err error) { branch := "master" path := filepath.Join(config.ChartLocation, config.FileName) exists, err := impl.checkIfFileExists(config.ChartRepoName, branch, path) diff --git a/pkg/app/AppService.go b/pkg/app/AppService.go index e2fee47f13..cf8e44e76e 100644 --- a/pkg/app/AppService.go +++ b/pkg/app/AppService.go @@ -139,6 +139,7 @@ type AppServiceImpl struct { pipelineStatusSyncDetailService PipelineStatusSyncDetailService pipelineStatusTimelineService PipelineStatusTimelineService appStatusConfig *AppStatusConfig + gitOpsConfigRepository repository.GitOpsConfigRepository } type AppService interface { @@ -193,7 +194,8 @@ func NewAppService( pipelineStatusTimelineResourcesService PipelineStatusTimelineResourcesService, pipelineStatusSyncDetailService PipelineStatusSyncDetailService, pipelineStatusTimelineService PipelineStatusTimelineService, - appStatusConfig *AppStatusConfig) *AppServiceImpl { + appStatusConfig *AppStatusConfig, + gitOpsConfigRepository repository.GitOpsConfigRepository) *AppServiceImpl { appServiceImpl := &AppServiceImpl{ environmentConfigRepository: environmentConfigRepository, mergeUtil: mergeUtil, @@ -244,6 +246,7 @@ func NewAppService( pipelineStatusSyncDetailService: pipelineStatusSyncDetailService, pipelineStatusTimelineService: pipelineStatusTimelineService, appStatusConfig: appStatusConfig, + gitOpsConfigRepository: gitOpsConfigRepository, } return appServiceImpl } @@ -1590,7 +1593,16 @@ func (impl *AppServiceImpl) mergeAndSave(envOverride *chartConfig.EnvConfigOverr UserName: userName, UserEmailId: userEmailId, } - commitHash, commitTime, err = impl.gitFactory.Client.CommitValues(chartGitAttr) + gitOpsConfigBitbucket, err := impl.gitOpsConfigRepository.GetGitOpsConfigByProvider(BITBUCKET_PROVIDER) + if err != nil { + if err == pg.ErrNoRows { + gitOpsConfigBitbucket.BitBucketWorkspaceId = "" + } else { + return 0, 0, "", err + } + } + gitOpsConfig := &bean.GitOpsConfigDto{BitBucketWorkspaceId: gitOpsConfigBitbucket.BitBucketWorkspaceId} + commitHash, commitTime, err = impl.gitFactory.Client.CommitValues(chartGitAttr, gitOpsConfig) if err != nil { impl.logger.Errorw("error in git commit", "err", err) return 0, 0, "", err diff --git a/pkg/appStore/deployment/fullMode/AppStoreDeploymentFullModeService.go b/pkg/appStore/deployment/fullMode/AppStoreDeploymentFullModeService.go index 69541e16b4..c8a7e90c0b 100644 --- a/pkg/appStore/deployment/fullMode/AppStoreDeploymentFullModeService.go +++ b/pkg/appStore/deployment/fullMode/AppStoreDeploymentFullModeService.go @@ -19,7 +19,9 @@ package appStoreDeploymentFullMode import ( "context" + "github.com/devtron-labs/devtron/api/bean" "github.com/devtron-labs/devtron/client/argocdServer" + repository3 "github.com/devtron-labs/devtron/internal/sql/repository" appStoreBean "github.com/devtron-labs/devtron/pkg/appStore/bean" repository4 "github.com/devtron-labs/devtron/pkg/appStore/deployment/repository" appStoreDiscoverRepository "github.com/devtron-labs/devtron/pkg/appStore/discover/repository" @@ -27,6 +29,7 @@ import ( util2 "github.com/devtron-labs/devtron/pkg/util" util3 "github.com/devtron-labs/devtron/util" "github.com/devtron-labs/devtron/util/argo" + "github.com/go-pg/pg" "encoding/json" "fmt" @@ -76,6 +79,7 @@ type AppStoreDeploymentFullModeServiceImpl struct { installedAppRepository repository4.InstalledAppRepository tokenCache *util2.TokenCache argoUserService argo.ArgoUserService + gitOpsConfigRepository repository3.GitOpsConfigRepository } func NewAppStoreDeploymentFullModeServiceImpl(logger *zap.SugaredLogger, @@ -88,7 +92,7 @@ func NewAppStoreDeploymentFullModeServiceImpl(logger *zap.SugaredLogger, gitFactory *util.GitFactory, aCDAuthConfig *util2.ACDAuthConfig, globalEnvVariables *util3.GlobalEnvVariables, installedAppRepository repository4.InstalledAppRepository, tokenCache *util2.TokenCache, - argoUserService argo.ArgoUserService) *AppStoreDeploymentFullModeServiceImpl { + argoUserService argo.ArgoUserService, gitOpsConfigRepository repository3.GitOpsConfigRepository) *AppStoreDeploymentFullModeServiceImpl { return &AppStoreDeploymentFullModeServiceImpl{ logger: logger, chartTemplateService: chartTemplateService, @@ -104,6 +108,7 @@ func NewAppStoreDeploymentFullModeServiceImpl(logger *zap.SugaredLogger, installedAppRepository: installedAppRepository, tokenCache: tokenCache, argoUserService: argoUserService, + gitOpsConfigRepository: gitOpsConfigRepository, } } @@ -163,6 +168,14 @@ func (impl AppStoreDeploymentFullModeServiceImpl) AppStoreDeployOperationGIT(ins gitOpsRepoName := impl.chartTemplateService.GetGitOpsRepoName(installAppVersionRequest.AppName) //getting user name & emailId for commit author data userEmailId, userName := impl.chartTemplateService.GetUserEmailIdAndNameForGitOpsCommit(installAppVersionRequest.UserId) + gitOpsConfigBitbucket, err := impl.gitOpsConfigRepository.GetGitOpsConfigByProvider(util.BITBUCKET_PROVIDER) + if err != nil { + if err == pg.ErrNoRows { + gitOpsConfigBitbucket.BitBucketWorkspaceId = "" + } else { + return installAppVersionRequest, nil, err + } + } requirmentYamlConfig := &util.ChartConfig{ FileName: appStoreBean.REQUIREMENTS_YAML_FILE, FileContent: string(requirementDependenciesByte), @@ -173,7 +186,8 @@ func (impl AppStoreDeploymentFullModeServiceImpl) AppStoreDeployOperationGIT(ins UserEmailId: userEmailId, UserName: userName, } - _, _, err = impl.gitFactory.Client.CommitValues(requirmentYamlConfig) + gitOpsConfig := &bean.GitOpsConfigDto{BitBucketWorkspaceId: gitOpsConfigBitbucket.BitBucketWorkspaceId} + _, _, err = impl.gitFactory.Client.CommitValues(requirmentYamlConfig, gitOpsConfig) if err != nil { impl.logger.Errorw("error in git commit", "err", err) return installAppVersionRequest, nil, err @@ -217,7 +231,7 @@ func (impl AppStoreDeploymentFullModeServiceImpl) AppStoreDeployOperationGIT(ins UserEmailId: userEmailId, UserName: userName, } - commitHash, _, err := impl.gitFactory.Client.CommitValues(valuesYamlConfig) + commitHash, _, err := impl.gitFactory.Client.CommitValues(valuesYamlConfig, gitOpsConfig) if err != nil { impl.logger.Errorw("error in git commit", "err", err) return installAppVersionRequest, nil, err @@ -357,6 +371,14 @@ func (impl AppStoreDeploymentFullModeServiceImpl) UpdateValuesYaml(installAppVer } //getting user name & emailId for commit author data userEmailId, userName := impl.chartTemplateService.GetUserEmailIdAndNameForGitOpsCommit(installAppVersionRequest.UserId) + gitOpsConfigBitbucket, err := impl.gitOpsConfigRepository.GetGitOpsConfigByProvider(util.BITBUCKET_PROVIDER) + if err != nil { + if err == pg.ErrNoRows { + gitOpsConfigBitbucket.BitBucketWorkspaceId = "" + } else { + return installAppVersionRequest, err + } + } valuesConfig := &util.ChartConfig{ FileName: appStoreBean.VALUES_YAML_FILE, FileContent: string(valuesByte), @@ -367,7 +389,8 @@ func (impl AppStoreDeploymentFullModeServiceImpl) UpdateValuesYaml(installAppVer UserEmailId: userEmailId, UserName: userName, } - commitHash, _, err := impl.gitFactory.Client.CommitValues(valuesConfig) + gitOpsConfig := &bean.GitOpsConfigDto{BitBucketWorkspaceId: gitOpsConfigBitbucket.BitBucketWorkspaceId} + commitHash, _, err := impl.gitFactory.Client.CommitValues(valuesConfig, gitOpsConfig) if err != nil { impl.logger.Errorw("error in git commit", "err", err) return installAppVersionRequest, err @@ -398,6 +421,14 @@ func (impl AppStoreDeploymentFullModeServiceImpl) UpdateRequirementYaml(installA } //getting user name & emailId for commit author data userEmailId, userName := impl.chartTemplateService.GetUserEmailIdAndNameForGitOpsCommit(installAppVersionRequest.UserId) + gitOpsConfigBitbucket, err := impl.gitOpsConfigRepository.GetGitOpsConfigByProvider(util.BITBUCKET_PROVIDER) + if err != nil { + if err == pg.ErrNoRows { + gitOpsConfigBitbucket.BitBucketWorkspaceId = "" + } else { + return err + } + } requirmentYamlConfig := &util.ChartConfig{ FileName: appStoreBean.REQUIREMENTS_YAML_FILE, FileContent: string(requirementDependenciesByte), @@ -408,7 +439,8 @@ func (impl AppStoreDeploymentFullModeServiceImpl) UpdateRequirementYaml(installA UserEmailId: userEmailId, UserName: userName, } - _, _, err = impl.gitFactory.Client.CommitValues(requirmentYamlConfig) + gitOpsConfig := &bean.GitOpsConfigDto{BitBucketWorkspaceId: gitOpsConfigBitbucket.BitBucketWorkspaceId} + _, _, err = impl.gitFactory.Client.CommitValues(requirmentYamlConfig, gitOpsConfig) if err != nil { impl.logger.Errorw("error in git commit", "err", err) return err diff --git a/pkg/appStore/deployment/service/InstalledAppService.go b/pkg/appStore/deployment/service/InstalledAppService.go index 6a213ef997..cca6276345 100644 --- a/pkg/appStore/deployment/service/InstalledAppService.go +++ b/pkg/appStore/deployment/service/InstalledAppService.go @@ -386,8 +386,12 @@ func (impl InstalledAppServiceImpl) performDeployStageOnAcd(installedAppVersion return nil, err } } - - repoUrl, err := impl.gitFactory.Client.GetRepoUrl(installedAppVersion.AppStoreName) + config := &bean2.GitOpsConfigDto{ + GitRepoName: installedAppVersion.GitOpsRepoName, + BitBucketWorkspaceId: gitOpsConfigBitbucket.BitBucketProjectKey, + BitBucketProjectKey: gitOpsConfigBitbucket.BitBucketProjectKey, + } + repoUrl, err := impl.gitFactory.Client.GetRepoUrl(config) if err != nil { //will allow to continue to persist status on next operation impl.logger.Errorw("fetching error", "err", err) diff --git a/pkg/appStore/deployment/tool/gitops/AppStoreDeploymentArgoCdService.go b/pkg/appStore/deployment/tool/gitops/AppStoreDeploymentArgoCdService.go index b7f5a1fba5..c37b3443ea 100644 --- a/pkg/appStore/deployment/tool/gitops/AppStoreDeploymentArgoCdService.go +++ b/pkg/appStore/deployment/tool/gitops/AppStoreDeploymentArgoCdService.go @@ -7,10 +7,12 @@ import ( "fmt" "github.com/argoproj/argo-cd/v2/pkg/apiclient/application" "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/devtron-labs/devtron/api/bean" client "github.com/devtron-labs/devtron/api/helm-app" openapi "github.com/devtron-labs/devtron/api/helm-app/openapiClient" application2 "github.com/devtron-labs/devtron/client/argocdServer/application" "github.com/devtron-labs/devtron/internal/constants" + repository3 "github.com/devtron-labs/devtron/internal/sql/repository" "github.com/devtron-labs/devtron/internal/util" appStoreBean "github.com/devtron-labs/devtron/pkg/appStore/bean" appStoreDeploymentCommon "github.com/devtron-labs/devtron/pkg/appStore/deployment/common" @@ -52,12 +54,14 @@ type AppStoreDeploymentArgoCdServiceImpl struct { gitFactory *util.GitFactory argoUserService argo.ArgoUserService appStoreDeploymentCommonService appStoreDeploymentCommon.AppStoreDeploymentCommonService + gitOpsConfigRepository repository3.GitOpsConfigRepository } func NewAppStoreDeploymentArgoCdServiceImpl(logger *zap.SugaredLogger, appStoreDeploymentFullModeService appStoreDeploymentFullMode.AppStoreDeploymentFullModeService, acdClient application2.ServiceClient, chartGroupDeploymentRepository repository.ChartGroupDeploymentRepository, installedAppRepository repository.InstalledAppRepository, installedAppRepositoryHistory repository.InstalledAppVersionHistoryRepository, chartTemplateService util.ChartTemplateService, - gitFactory *util.GitFactory, argoUserService argo.ArgoUserService, appStoreDeploymentCommonService appStoreDeploymentCommon.AppStoreDeploymentCommonService) *AppStoreDeploymentArgoCdServiceImpl { + gitFactory *util.GitFactory, argoUserService argo.ArgoUserService, appStoreDeploymentCommonService appStoreDeploymentCommon.AppStoreDeploymentCommonService, + gitOpsConfigRepository repository3.GitOpsConfigRepository) *AppStoreDeploymentArgoCdServiceImpl { return &AppStoreDeploymentArgoCdServiceImpl{ Logger: logger, appStoreDeploymentFullModeService: appStoreDeploymentFullModeService, @@ -69,6 +73,7 @@ func NewAppStoreDeploymentArgoCdServiceImpl(logger *zap.SugaredLogger, appStoreD gitFactory: gitFactory, argoUserService: argoUserService, appStoreDeploymentCommonService: appStoreDeploymentCommonService, + gitOpsConfigRepository: gitOpsConfigRepository, } } @@ -365,6 +370,14 @@ func (impl *AppStoreDeploymentArgoCdServiceImpl) UpdateRequirementDependencies(e } //getting user name & emailId for commit author data userEmailId, userName := impl.chartTemplateService.GetUserEmailIdAndNameForGitOpsCommit(installAppVersionRequest.UserId) + gitOpsConfigBitbucket, err := impl.gitOpsConfigRepository.GetGitOpsConfigByProvider(util.BITBUCKET_PROVIDER) + if err != nil { + if err == pg.ErrNoRows { + gitOpsConfigBitbucket.BitBucketWorkspaceId = "" + } else { + return err + } + } requirmentYamlConfig := &util.ChartConfig{ FileName: appStoreBean.REQUIREMENTS_YAML_FILE, FileContent: string(requirementDependenciesByte), @@ -375,7 +388,8 @@ func (impl *AppStoreDeploymentArgoCdServiceImpl) UpdateRequirementDependencies(e UserEmailId: userEmailId, UserName: userName, } - _, _, err = impl.gitFactory.Client.CommitValues(requirmentYamlConfig) + gitOpsConfig := &bean.GitOpsConfigDto{BitBucketWorkspaceId: gitOpsConfigBitbucket.BitBucketWorkspaceId} + _, _, err = impl.gitFactory.Client.CommitValues(requirmentYamlConfig, gitOpsConfig) if err != nil { impl.Logger.Errorw("error in git commit", "err", err) return err @@ -458,6 +472,14 @@ func (impl AppStoreDeploymentArgoCdServiceImpl) updateValuesYaml(environment *cl } //getting user name & emailId for commit author data userEmailId, userName := impl.chartTemplateService.GetUserEmailIdAndNameForGitOpsCommit(installAppVersionRequest.UserId) + gitOpsConfigBitbucket, err := impl.gitOpsConfigRepository.GetGitOpsConfigByProvider(util.BITBUCKET_PROVIDER) + if err != nil { + if err == pg.ErrNoRows { + gitOpsConfigBitbucket.BitBucketWorkspaceId = "" + } else { + return installAppVersionRequest, err + } + } valuesConfig := &util.ChartConfig{ FileName: appStoreBean.VALUES_YAML_FILE, FileContent: string(valuesByte), @@ -468,7 +490,8 @@ func (impl AppStoreDeploymentArgoCdServiceImpl) updateValuesYaml(environment *cl UserEmailId: userEmailId, UserName: userName, } - commitHash, _, err := impl.gitFactory.Client.CommitValues(valuesConfig) + gitOpsConfig := &bean.GitOpsConfigDto{BitBucketWorkspaceId: gitOpsConfigBitbucket.BitBucketWorkspaceId} + commitHash, _, err := impl.gitFactory.Client.CommitValues(valuesConfig, gitOpsConfig) if err != nil { impl.Logger.Errorw("error in git commit", "err", err) return installAppVersionRequest, err diff --git a/pkg/gitops/GitOpsConfigService.go b/pkg/gitops/GitOpsConfigService.go index 3500a1a498..115831c7d7 100644 --- a/pkg/gitops/GitOpsConfigService.go +++ b/pkg/gitops/GitOpsConfigService.go @@ -701,7 +701,9 @@ func (impl *GitOpsConfigServiceImpl) GitOpsValidateDryRun(config *bean2.GitOpsCo appName := DryrunRepoName + util2.Generate(6) //getting user name & emailId for commit author data userEmailId, userName := impl.chartTemplateService.GetUserEmailIdAndNameForGitOpsCommit(config.UserId) - repoUrl, _, detailedErrorCreateRepo := client.CreateRepository(appName, "sample dry-run repo", userName, userEmailId) + config.UserEmailId = userEmailId + config.GitRepoName = appName + repoUrl, _, detailedErrorCreateRepo := client.CreateRepository(config) detailedErrorGitOpsConfigActions.StageErrorMap = detailedErrorCreateRepo.StageErrorMap detailedErrorGitOpsConfigActions.SuccessfulStages = detailedErrorCreateRepo.SuccessfulStages @@ -746,7 +748,7 @@ func (impl *GitOpsConfigServiceImpl) GitOpsValidateDryRun(config *bean2.GitOpsCo detailedErrorGitOpsConfigActions.SuccessfulStages = append(detailedErrorGitOpsConfigActions.SuccessfulStages, CommitOnRestStage, PushStage) } - err = client.DeleteRepository(appName) + err = client.DeleteRepository(config) if err != nil { impl.logger.Errorw("error in deleting repo", "err", err) //here below the assignment of delete is removed for making this stage optional, and it's failure not preventing it from saving/updating gitOps config diff --git a/wire_gen.go b/wire_gen.go index ec7ab4071e..6dbe7cb0d4 100644 --- a/wire_gen.go +++ b/wire_gen.go @@ -331,7 +331,7 @@ func InitializeApp() (*App, error) { if err != nil { return nil, err } - appServiceImpl := app2.NewAppService(envConfigOverrideRepositoryImpl, pipelineOverrideRepositoryImpl, mergeUtil, sugaredLogger, ciArtifactRepositoryImpl, pipelineRepositoryImpl, dbMigrationConfigRepositoryImpl, eventRESTClientImpl, eventSimpleFactoryImpl, applicationServiceClientImpl, tokenCache, acdAuthConfig, enforcerImpl, enforcerUtilImpl, userServiceImpl, appListingRepositoryImpl, appRepositoryImpl, environmentRepositoryImpl, pipelineConfigRepositoryImpl, configMapRepositoryImpl, appLevelMetricsRepositoryImpl, envLevelAppMetricsRepositoryImpl, chartRepositoryImpl, ciPipelineMaterialRepositoryImpl, cdWorkflowRepositoryImpl, commonServiceImpl, imageScanDeployInfoRepositoryImpl, imageScanHistoryRepositoryImpl, argoK8sClientImpl, gitFactory, pipelineStrategyHistoryServiceImpl, configMapHistoryServiceImpl, deploymentTemplateHistoryServiceImpl, chartTemplateServiceImpl, refChartDir, chartRefRepositoryImpl, chartServiceImpl, helmAppClientImpl, argoUserServiceImpl, pipelineStatusTimelineRepositoryImpl, appCrudOperationServiceImpl, configMapHistoryRepositoryImpl, pipelineStrategyHistoryRepositoryImpl, deploymentTemplateHistoryRepositoryImpl, dockerRegistryIpsConfigServiceImpl, pipelineStatusTimelineResourcesServiceImpl, pipelineStatusSyncDetailServiceImpl, pipelineStatusTimelineServiceImpl, appStatusConfig) + appServiceImpl := app2.NewAppService(envConfigOverrideRepositoryImpl, pipelineOverrideRepositoryImpl, mergeUtil, sugaredLogger, ciArtifactRepositoryImpl, pipelineRepositoryImpl, dbMigrationConfigRepositoryImpl, eventRESTClientImpl, eventSimpleFactoryImpl, applicationServiceClientImpl, tokenCache, acdAuthConfig, enforcerImpl, enforcerUtilImpl, userServiceImpl, appListingRepositoryImpl, appRepositoryImpl, environmentRepositoryImpl, pipelineConfigRepositoryImpl, configMapRepositoryImpl, appLevelMetricsRepositoryImpl, envLevelAppMetricsRepositoryImpl, chartRepositoryImpl, ciPipelineMaterialRepositoryImpl, cdWorkflowRepositoryImpl, commonServiceImpl, imageScanDeployInfoRepositoryImpl, imageScanHistoryRepositoryImpl, argoK8sClientImpl, gitFactory, pipelineStrategyHistoryServiceImpl, configMapHistoryServiceImpl, deploymentTemplateHistoryServiceImpl, chartTemplateServiceImpl, refChartDir, chartRefRepositoryImpl, chartServiceImpl, helmAppClientImpl, argoUserServiceImpl, pipelineStatusTimelineRepositoryImpl, appCrudOperationServiceImpl, configMapHistoryRepositoryImpl, pipelineStrategyHistoryRepositoryImpl, deploymentTemplateHistoryRepositoryImpl, dockerRegistryIpsConfigServiceImpl, pipelineStatusTimelineResourcesServiceImpl, pipelineStatusSyncDetailServiceImpl, pipelineStatusTimelineServiceImpl, appStatusConfig, gitOpsConfigRepositoryImpl) validate, err := util.IntValidator() if err != nil { return nil, err @@ -437,12 +437,12 @@ func InitializeApp() (*App, error) { appStoreVersionValuesRepositoryImpl := appStoreValuesRepository.NewAppStoreVersionValuesRepositoryImpl(sugaredLogger, db) appStoreValuesServiceImpl := service.NewAppStoreValuesServiceImpl(sugaredLogger, appStoreApplicationVersionRepositoryImpl, installedAppRepositoryImpl, appStoreVersionValuesRepositoryImpl, userServiceImpl) chartGroupDeploymentRepositoryImpl := repository3.NewChartGroupDeploymentRepositoryImpl(db, sugaredLogger) - appStoreDeploymentFullModeServiceImpl := appStoreDeploymentFullMode.NewAppStoreDeploymentFullModeServiceImpl(sugaredLogger, chartTemplateServiceImpl, refChartProxyDir, repositoryServiceClientImpl, appStoreApplicationVersionRepositoryImpl, environmentRepositoryImpl, applicationServiceClientImpl, argoK8sClientImpl, gitFactory, acdAuthConfig, globalEnvVariables, installedAppRepositoryImpl, tokenCache, argoUserServiceImpl) + appStoreDeploymentFullModeServiceImpl := appStoreDeploymentFullMode.NewAppStoreDeploymentFullModeServiceImpl(sugaredLogger, chartTemplateServiceImpl, refChartProxyDir, repositoryServiceClientImpl, appStoreApplicationVersionRepositoryImpl, environmentRepositoryImpl, applicationServiceClientImpl, argoK8sClientImpl, gitFactory, acdAuthConfig, globalEnvVariables, installedAppRepositoryImpl, tokenCache, argoUserServiceImpl, gitOpsConfigRepositoryImpl) clusterInstalledAppsRepositoryImpl := repository3.NewClusterInstalledAppsRepositoryImpl(db, sugaredLogger) appStoreDeploymentHelmServiceImpl := appStoreDeploymentTool.NewAppStoreDeploymentHelmServiceImpl(sugaredLogger, helmAppServiceImpl, appStoreApplicationVersionRepositoryImpl, environmentRepositoryImpl, helmAppClientImpl, installedAppRepositoryImpl) installedAppVersionHistoryRepositoryImpl := repository3.NewInstalledAppVersionHistoryRepositoryImpl(sugaredLogger, db) appStoreDeploymentCommonServiceImpl := appStoreDeploymentCommon.NewAppStoreDeploymentCommonServiceImpl(sugaredLogger, installedAppRepositoryImpl) - appStoreDeploymentArgoCdServiceImpl := appStoreDeploymentGitopsTool.NewAppStoreDeploymentArgoCdServiceImpl(sugaredLogger, appStoreDeploymentFullModeServiceImpl, applicationServiceClientImpl, chartGroupDeploymentRepositoryImpl, installedAppRepositoryImpl, installedAppVersionHistoryRepositoryImpl, chartTemplateServiceImpl, gitFactory, argoUserServiceImpl, appStoreDeploymentCommonServiceImpl) + appStoreDeploymentArgoCdServiceImpl := appStoreDeploymentGitopsTool.NewAppStoreDeploymentArgoCdServiceImpl(sugaredLogger, appStoreDeploymentFullModeServiceImpl, applicationServiceClientImpl, chartGroupDeploymentRepositoryImpl, installedAppRepositoryImpl, installedAppVersionHistoryRepositoryImpl, chartTemplateServiceImpl, gitFactory, argoUserServiceImpl, appStoreDeploymentCommonServiceImpl, gitOpsConfigRepositoryImpl) serviceDeploymentServiceTypeConfig, err := service2.GetDeploymentServiceTypeConfig() if err != nil { return nil, err