Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 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
28 changes: 16 additions & 12 deletions client/argocdServer/ArgoClientWrapperService.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,9 @@ import (
)

type ACDConfig struct {
ArgoCDAutoSyncEnabled bool `env:"ARGO_AUTO_SYNC_ENABLED" envDefault:"true" description:"If enabled all argocd application will have auto sync enabled"` // will gradually switch this flag to false in enterprise
RegisterRepoMaxRetryCount int `env:"ARGO_REPO_REGISTER_RETRY_COUNT" envDefault:"3" description:"Argo app registration in argo retries on deployment"`
RegisterRepoMaxRetryDelay int `env:"ARGO_REPO_REGISTER_RETRY_DELAY" envDefault:"10" description:"Argo app registration in argo cd on deployment delay between retry"`
ArgoCDAutoSyncEnabled bool `env:"ARGO_AUTO_SYNC_ENABLED" envDefault:"true" description:"If enabled all argocd application will have auto sync enabled" example:"true" deprecated:"false"` // will gradually switch this flag to false in enterprise
RegisterRepoMaxRetryCount int `env:"ARGO_REPO_REGISTER_RETRY_COUNT" envDefault:"3" description:"Retry count for registering a GitOps repository to ArgoCD" example:"3" deprecated:"false"`
RegisterRepoMaxRetryDelay int `env:"ARGO_REPO_REGISTER_RETRY_DELAY" envDefault:"5" description:"Delay (in Seconds) between the retries for registering a GitOps repository to ArgoCD" example:"5" deprecated:"false"`
}

func (config *ACDConfig) IsManualSyncEnabled() bool {
Expand Down Expand Up @@ -105,7 +105,7 @@ type ApplicationClientWrapper interface {
// IsArgoAppPatchRequired decides weather the v1alpha1.ApplicationSource requires to be updated
IsArgoAppPatchRequired(argoAppSpec *v1alpha1.ApplicationSource, currentGitRepoUrl, currentTargetRevision, currentChartPath string) bool

// GetGitOpsRepoName returns the GitOps repository name, configured for the argoCd app
// GetGitOpsRepoNameForApplication returns the GitOps repository name, configured for the argoCd app
GetGitOpsRepoNameForApplication(ctx context.Context, appName string) (gitOpsRepoName string, err error)

GetGitOpsRepoURLForApplication(ctx context.Context, appName string) (gitOpsRepoURL string, err error)
Expand All @@ -127,6 +127,7 @@ type RepoCredsClientWrapper interface {
type CertificateClientWrapper interface {
CreateCertificate(ctx context.Context, query *certificate.RepositoryCertificateCreateRequest) (*v1alpha1.RepositoryCertificateList, error)
DeleteCertificate(ctx context.Context, query *certificate.RepositoryCertificateQuery, opts ...grpc.CallOption) (*v1alpha1.RepositoryCertificateList, error)
CertificateClientWrapperEnt
}

type ClusterClientWrapper interface {
Expand All @@ -147,7 +148,7 @@ type ArgoClientWrapperServiceImpl struct {
repositoryService repository.ServiceClient
clusterClient cluster.ServiceClient
repoCredsClient repocreds2.ServiceClient
CertificateClient certificate2.ServiceClient
certificateClient certificate2.ServiceClient
logger *zap.SugaredLogger
ACDConfig *ACDConfig
gitOpsConfigReadService config.GitOpsConfigReadService
Expand Down Expand Up @@ -176,7 +177,7 @@ func NewArgoClientWrapperServiceImpl(
repositoryService: repositoryService,
clusterClient: clusterClient,
repoCredsClient: repocredsClient,
CertificateClient: CertificateClient,
certificateClient: CertificateClient,
logger: logger,
ACDConfig: ACDConfig,
gitOpsConfigReadService: gitOpsConfigReadService,
Expand Down Expand Up @@ -521,7 +522,7 @@ func (impl *ArgoClientWrapperServiceImpl) createRepoInArgoCd(ctx context.Context
}
repo, err := impl.repositoryService.Create(ctx, grpcConfig, &repository2.RepoCreateRequest{Repo: repo, Upsert: true})
if err != nil {
impl.logger.Errorw("error in creating argo Repository", "err", err)
impl.logger.Errorw("error in creating argo Repository", "err", err, "url", gitOpsRepoUrl)
return err
}
return nil
Expand All @@ -543,15 +544,18 @@ func (impl *ArgoClientWrapperServiceImpl) handleArgoRepoCreationError(ctx contex
}
}
if isEmptyRepoError {
// - found empty repository, create some file in repository
impl.logger.Infow("handling for empty repo", "url", gitOpsRepoUrl)
// - found empty repository (there is no origin/HEAD)
// - create new commit on HEAD (default branch) with a README file
// - then register the repository in ArgoCD
gitOpsRepoName := impl.gitOpsConfigReadService.GetGitOpsRepoNameFromUrl(gitOpsRepoUrl)
err := impl.gitOperationService.CreateReadmeInGitRepo(ctx, gitOpsRepoName, targetRevision, userId)
err := impl.gitOperationService.CreateFirstCommitOnHead(ctx, gitOpsRepoName, userId)
if err != nil {
impl.logger.Errorw("error in creating file in git repo", "err", err)
return err
}
}
// try to register with after creating readme file
// try to register with after commiting a file to origin/HEAD
return impl.createRepoInArgoCd(ctx, grpcConfig, gitOpsRepoUrl)
}

Expand Down Expand Up @@ -586,13 +590,13 @@ func (impl *ArgoClientWrapperServiceImpl) CreateCertificate(ctx context.Context,
if err != nil {
return nil, err
}
return impl.CertificateClient.CreateCertificate(ctx, grpcConfig, query)
return impl.certificateClient.CreateCertificate(ctx, grpcConfig, query)
}

func (impl *ArgoClientWrapperServiceImpl) DeleteCertificate(ctx context.Context, query *certificate.RepositoryCertificateQuery, opts ...grpc.CallOption) (*v1alpha1.RepositoryCertificateList, error) {
grpcConfig, err := impl.acdConfigGetter.GetGRPCConfig()
if err != nil {
return nil, err
}
return impl.CertificateClient.DeleteCertificate(ctx, grpcConfig, query, opts...)
return impl.certificateClient.DeleteCertificate(ctx, grpcConfig, query, opts...)
}
20 changes: 20 additions & 0 deletions client/argocdServer/ArgoClientWrapperService_ent.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*
* Copyright (c) 2024. Devtron Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package argocdServer

type CertificateClientWrapperEnt interface {
}
3 changes: 2 additions & 1 deletion client/argocdServer/bean/bean.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ const RegisterRepoMaxRetryCount = 3
var EmptyRepoErrorList = []string{"failed to get index: 404 Not Found", "remote repository is empty"}

// ArgoRepoSyncDelayErr - This error occurs inconsistently; ArgoCD requires 80-120s after last commit for create repository operation
const ArgoRepoSyncDelayErr = "Unable to resolve 'HEAD' to a commit SHA"
// Error message reference: https://github.com/argoproj/argo-cd/blob/master/util/git/client.go#L718
const ArgoRepoSyncDelayErr = "unable to resolve 'HEAD' to a commit SHA"

const (
Degraded = "Degraded"
Expand Down
1 change: 0 additions & 1 deletion client/argocdServer/k8sClient.go
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,6 @@ func (impl ArgoK8sClientImpl) DeleteArgoApplication(ctx context.Context, k8sConf
patchType := types.MergePatchType
patchJSON := ""

//TODO: ayush test cascade delete
if cascadeDelete {
patchJSON = `{"metadata": {"finalizers": ["resources-finalizer.argocd.argoproj.io"]}}`
} else {
Expand Down
2 changes: 1 addition & 1 deletion env_gen.json

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions env_gen.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,11 +131,11 @@
| APP_SYNC_JOB_RESOURCES_OBJ | string | | To pass the resource of app sync | | false |
| APP_SYNC_SERVICE_ACCOUNT | string |chart-sync | Service account to be used in app sync Job | | false |
| APP_SYNC_SHUTDOWN_WAIT_DURATION | int |120 | | | false |
| ARGO_AUTO_SYNC_ENABLED | bool |true | If enabled all argocd application will have auto sync enabled | | false |
| ARGO_AUTO_SYNC_ENABLED | bool |true | If enabled all argocd application will have auto sync enabled | true | false |
| ARGO_GIT_COMMIT_RETRY_COUNT_ON_CONFLICT | int |3 | retry argocd app manual sync if the timeline is stuck in ARGOCD_SYNC_INITIATED state for more than this defined time (in mins) | | false |
| ARGO_GIT_COMMIT_RETRY_DELAY_ON_CONFLICT | int |1 | Delay on retrying the maifest commit the on gitops | | false |
| ARGO_REPO_REGISTER_RETRY_COUNT | int |3 | Argo app registration in argo retries on deployment | | false |
| ARGO_REPO_REGISTER_RETRY_DELAY | int |10 | Argo app registration in argo cd on deployment delay between retry | | false |
| ARGO_REPO_REGISTER_RETRY_COUNT | int |3 | Retry count for registering a GitOps repository to ArgoCD | 3 | false |
| ARGO_REPO_REGISTER_RETRY_DELAY | int |5 | Delay (in Seconds) between the retries for registering a GitOps repository to ArgoCD | 5 | false |
| ASYNC_BUILDX_CACHE_EXPORT | bool |false | To enable async container image cache export | | false |
| BATCH_SIZE | int |5 | there is feature to get URL's of services/ingresses. so to extract those, we need to parse all the servcie and ingress objects of the application. this BATCH_SIZE flag controls the no of these objects get parsed in one go. | | false |
| BLOB_STORAGE_ENABLED | bool |false | | | false |
Expand Down
8 changes: 8 additions & 0 deletions internal/sql/repository/GitOpsConfigRepository.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ type GitOpsConfigRepository interface {
GetAllGitOpsConfig() ([]*GitOpsConfig, error)
GetAllGitOpsConfigCount() (int, error)
GetGitOpsConfigByProvider(provider string) (*GitOpsConfig, error)
CheckIfGitOpsProviderExist(provider string) (bool, error)
GetGitOpsConfigActive() (*GitOpsConfig, error)
GetConnection() *pg.DB
GetEmailIdFromActiveGitOpsConfig() (string, error)
Expand Down Expand Up @@ -105,6 +106,13 @@ func (impl *GitOpsConfigRepositoryImpl) GetGitOpsConfigByProvider(provider strin
return &model, err
}

func (impl *GitOpsConfigRepositoryImpl) CheckIfGitOpsProviderExist(provider string) (bool, error) {
found, err := impl.dbConnection.Model((*GitOpsConfig)(nil)).
Where("provider = ?", provider).
Exists()
return found, err
}

func (impl *GitOpsConfigRepositoryImpl) GetGitOpsConfigActive() (*GitOpsConfig, error) {
var model GitOpsConfig
err := impl.dbConnection.Model(&model).Where("active = ?", true).Limit(1).Select()
Expand Down
15 changes: 10 additions & 5 deletions pkg/deployment/gitOps/git/GitFactory.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,7 @@ type GitFactory struct {
logger *zap.SugaredLogger
}

func (factory *GitFactory) Reload(gitOpsConfigReadService config.GitOpsConfigReadService) error {
var err error
func (factory *GitFactory) Reload(gitOpsConfigReadService config.GitOpsConfigReadService) (err error) {
start := time.Now()
defer func() {
util.TriggerGitOpsMetrics("Reload", "GitService", start, err)
Expand Down Expand Up @@ -96,8 +95,11 @@ func (factory *GitFactory) NewClientForValidation(gitOpsConfig *gitOps.GitOpsCon
}()
cfg := adapter.ConvertGitOpsConfigToGitConfig(gitOpsConfig)
//factory.GitOpsHelper.SetAuth(cfg.GetAuth())
gitOpsHelper := NewGitOpsHelperImpl(cfg.GetAuth(), factory.logger, cfg.GetTLSConfig(), gitOpsConfig.EnableTLSVerification)

gitOpsHelper, err := NewGitOpsHelperImpl(cfg.GetAuth(), factory.logger, cfg.GetTLSConfig(), gitOpsConfig.EnableTLSVerification)
if err != nil {
factory.logger.Errorw("error in creating gitOps helper", "err", err, "gitProvider", cfg.GitProvider)
return nil, nil, err
}
client, err := NewGitOpsClient(cfg, factory.logger, gitOpsHelper)
if err != nil {
return client, gitOpsHelper, err
Expand All @@ -113,7 +115,10 @@ func NewGitFactory(logger *zap.SugaredLogger, gitOpsConfigReadService config.Git
if err != nil {
return nil, err
}
gitOpsHelper := NewGitOpsHelperImpl(cfg.GetAuth(), logger, cfg.GetTLSConfig(), cfg.EnableTLSVerification)
gitOpsHelper, err := NewGitOpsHelperImpl(cfg.GetAuth(), logger, cfg.GetTLSConfig(), cfg.EnableTLSVerification)
if err != nil {
logger.Errorw("error in creating gitOps helper", "err", err, "gitProvider", cfg.GitProvider)
}
client, err := NewGitOpsClient(cfg, logger, gitOpsHelper)
if err != nil {
logger.Errorw("error in creating gitOps client", "err", err, "gitProvider", cfg.GitProvider)
Expand Down
9 changes: 5 additions & 4 deletions pkg/deployment/gitOps/git/GitOperationService.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,9 @@ import (

type GitOperationService interface {
CreateGitRepositoryForDevtronApp(ctx context.Context, gitOpsRepoName string, targetRevision string, userId int32) (chartGitAttribute *commonBean.ChartGitAttribute, err error)
CreateReadmeInGitRepo(ctx context.Context, gitOpsRepoName string, targetRevision string, userId int32) error
// CreateFirstCommitOnHead - creates the first commit on the head of the git repository (mostly empty).
// To register the git repository in ArgoCD, there should be a commit HEAD on the default branch.
CreateFirstCommitOnHead(ctx context.Context, gitOpsRepoName string, userId int32) error
GitPull(clonedDir string, repoUrl string, targetRevision string) error

CommitValues(ctx context.Context, chartGitAttr *ChartConfig) (commitHash string, commitTime time.Time, err error)
Expand Down Expand Up @@ -210,7 +212,7 @@ func (impl *GitOperationServiceImpl) updateRepoAndPushAllChanges(ctx context.Con
return commit, nil
}

func (impl *GitOperationServiceImpl) CreateReadmeInGitRepo(ctx context.Context, gitOpsRepoName string, targetRevision string, userId int32) error {
func (impl *GitOperationServiceImpl) CreateFirstCommitOnHead(ctx context.Context, gitOpsRepoName string, userId int32) error {
userEmailId, userName := impl.gitOpsConfigReadService.GetUserEmailIdAndNameForGitOpsCommit(userId)
gitOpsConfig, err := impl.gitOpsConfigReadService.GetGitOpsConfigActive()
if err != nil {
Expand All @@ -222,9 +224,8 @@ func (impl *GitOperationServiceImpl) CreateReadmeInGitRepo(ctx context.Context,
gitOpsConfig.UserEmailId = userEmailId
gitOpsConfig.Username = userName
gitOpsConfig.GitRepoName = gitOpsRepoName
gitOpsConfig.TargetRevision = targetRevision
}
_, err = impl.gitFactory.Client.CreateReadme(ctx, gitOpsConfig)
_, err = impl.gitFactory.Client.CreateFirstCommitOnHead(ctx, gitOpsConfig)
if err != nil {
impl.logger.Errorw("error in creating readme", "err", err, "gitOpsRepoName", gitOpsRepoName, "userId", userId)
return err
Expand Down
3 changes: 3 additions & 0 deletions pkg/deployment/gitOps/git/GitOpsClient.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ type GitOpsClient interface {
GetRepoUrl(config *gitOps.GitOpsConfigDto) (repoUrl string, isRepoEmpty bool, err error)
DeleteRepository(config *gitOps.GitOpsConfigDto) error
CreateReadme(ctx context.Context, config *gitOps.GitOpsConfigDto) (string, error)
// CreateFirstCommitOnHead creates a commit on the HEAD of the repository, used for initializing the repository.
// It is used when the repository is empty and needs an initial commit.
CreateFirstCommitOnHead(ctx context.Context, config *gitOps.GitOpsConfigDto) (string, error)
}

func GetGitConfig(gitOpsConfigReadService config.GitOpsConfigReadService) (*bean.GitConfig, error) {
Expand Down
Loading
Loading