@@ -20,6 +20,7 @@ package chartRepo
2020import (
2121 "bytes"
2222 "encoding/json"
23+ "errors"
2324 "fmt"
2425 "github.com/devtron-labs/devtron/internal/sql/repository"
2526 "github.com/devtron-labs/devtron/internal/util"
@@ -99,22 +100,42 @@ func NewChartRepositoryServiceImpl(logger *zap.SugaredLogger, repoRepository cha
99100}
100101
101102// Private helm charts credentials are saved as secrets
102- func (impl * ChartRepositoryServiceImpl ) CreateSecretDataForPrivateHelmChart (request * ChartRepoDto ) (secretData map [string ]string ) {
103+ func (impl * ChartRepositoryServiceImpl ) CreateSecretDataForHelmChart (request * ChartRepoDto , isPrivateChart bool ) (secretData map [string ]string ) {
103104 secretData = make (map [string ]string )
104- secretData [NAME ] = fmt .Sprintf ("%s-%s" , request .Name , uuid .New ().String ()) // making repo name unique so that "helm repp add" command in argo-repo-server doesn't give error
105- secretData [USERNAME ] = request .UserName
106- secretData [PASSWORD ] = request .Password
105+ secretData [NAME ] = fmt .Sprintf ("%s-%s" , request .Name , uuid .New ().String ()) // making repo name unique so that "helm repo add" command in argo-repo-server doesn't give error
107106 secretData [TYPE ] = HELM
108107 secretData [URL ] = request .Url
109- isInsecureConnection := "true"
110- if ! request .AllowInsecureConnection {
111- isInsecureConnection = "false"
108+ if isPrivateChart {
109+ secretData [USERNAME ] = request .UserName
110+ secretData [PASSWORD ] = request .Password
111+ isInsecureConnection := "true"
112+ if ! request .AllowInsecureConnection {
113+ isInsecureConnection = "false"
114+ }
115+ secretData [INSECRUE ] = isInsecureConnection
112116 }
113- secretData [ INSECRUE ] = isInsecureConnection
117+
114118 return secretData
115119}
116120
117121func (impl * ChartRepositoryServiceImpl ) CreateChartRepo (request * ChartRepoDto ) (* chartRepoRepository.ChartRepo , error ) {
122+ //metadata.name label in Secret doesn't support uppercase hence returning if user enters uppercase letters
123+ if strings .ToLower (request .Name ) != request .Name {
124+ return nil , errors .New ("invalid repo name: please use lowercase" )
125+ }
126+ allChartsRepos , err := impl .repoRepository .FindAll ()
127+ if err != nil {
128+ impl .logger .Errorw ("error in getting list of all chart repos" , "err" , err )
129+ return nil , err
130+ }
131+ if len (allChartsRepos ) == 0 {
132+ return nil , nil
133+ }
134+ for _ , chart := range allChartsRepos {
135+ if chart .Name == request .Name {
136+ return nil , errors .New ("repo with chart name already exists" )
137+ }
138+ }
118139 dbConnection := impl .repoRepository .GetConnection ()
119140 tx , err := dbConnection .Begin ()
120141 if err != nil {
@@ -166,24 +187,10 @@ func (impl *ChartRepositoryServiceImpl) CreateChartRepo(request *ChartRepoDto) (
166187 for ! updateSuccess && retryCount < 3 {
167188 retryCount = retryCount + 1
168189
169- if ! isPrivateChart {
170- cm , err := impl .K8sUtil .GetConfigMap (impl .aCDAuthConfig .ACDConfigMapNamespace , impl .aCDAuthConfig .ACDConfigMapName , client )
171- if err != nil {
172- return nil , err
173- }
174- data , err := impl .updateRepoData (cm .Data , request )
175- if err != nil {
176- impl .logger .Warnw (" config map update failed" , "err" , err )
177- continue
178- }
179- cm .Data = data
180- _ , err = impl .K8sUtil .UpdateConfigMap (impl .aCDAuthConfig .ACDConfigMapNamespace , cm , client )
181- } else {
182- secretLabel := make (map [string ]string )
183- secretLabel [LABEL ] = REPOSITORY
184- secretData := impl .CreateSecretDataForPrivateHelmChart (request )
185- _ , err = impl .K8sUtil .CreateSecret (impl .aCDAuthConfig .ACDConfigMapNamespace , nil , chartRepo .Name , "" , client , secretLabel , secretData )
186- }
190+ secretLabel := make (map [string ]string )
191+ secretLabel [LABEL ] = REPOSITORY
192+ secretData := impl .CreateSecretDataForHelmChart (request , isPrivateChart )
193+ _ , err = impl .K8sUtil .CreateSecret (impl .aCDAuthConfig .ACDConfigMapNamespace , nil , chartRepo .Name , "" , client , secretLabel , secretData )
187194 if err != nil {
188195 continue
189196 }
@@ -215,7 +222,11 @@ func (impl *ChartRepositoryServiceImpl) UpdateData(request *ChartRepoDto) (*char
215222 return nil , err
216223 }
217224 previousName := chartRepo .Name
218-
225+ previousUrl := chartRepo .Url
226+ //metadata.name label in Secret doesn't support uppercase hence returning if user enters uppercase letters in repo name
227+ if request .Name != previousName && strings .ToLower (request .Name ) != request .Name {
228+ return nil , errors .New ("invalid repo name: please use lowercase" )
229+ }
219230 chartRepo .Url = request .Url
220231 chartRepo .Name = request .Name
221232 chartRepo .AuthMode = request .AuthMode
@@ -257,31 +268,55 @@ func (impl *ChartRepositoryServiceImpl) UpdateData(request *ChartRepoDto) (*char
257268 for ! updateSuccess && retryCount < 3 {
258269 retryCount = retryCount + 1
259270
260- if ! isPrivateChart {
261- cm , err := impl .K8sUtil .GetConfigMap (impl .aCDAuthConfig .ACDConfigMapNamespace , impl .aCDAuthConfig .ACDConfigMapName , client )
271+ var isFoundInArgoCdCm bool
272+ cm , err := impl .K8sUtil .GetConfigMap (impl .aCDAuthConfig .ACDConfigMapNamespace , impl .aCDAuthConfig .ACDConfigMapName , client )
273+ if err != nil {
274+ return nil , err
275+ }
276+ var repositories []* AcdConfigMapRepositoriesDto
277+ if cm != nil && cm .Data != nil {
278+ repoStr := cm .Data ["repositories" ]
279+ repoByte , err := yaml .YAMLToJSON ([]byte (repoStr ))
262280 if err != nil {
281+ impl .logger .Errorw ("error in json patch" , "err" , err )
263282 return nil , err
264283 }
265- var data map [string ]string
266- // if the repo name has been updated then, create a new repo
267- data , err = impl .updateRepoData (cm .Data , request )
268- // if the repo name has been updated then, delete the previous repo
284+ err = json .Unmarshal (repoByte , & repositories )
269285 if err != nil {
270- impl .logger .Warnw (" config map update failed" , "err" , err )
271- continue
272- }
273- if previousName != request .Name {
274- data , err = impl .removeRepoData (cm .Data , previousName )
286+ impl .logger .Errorw ("error in unmarshal" , "err" , err )
287+ return nil , err
275288 }
276- if err != nil {
277- impl .logger .Warnw (" config map update failed" , "err" , err )
278- continue
289+ for _ , repo := range repositories {
290+ if repo .Name == previousName && repo .Url == previousUrl {
291+ //chart repo is present in argocd-cm
292+ isFoundInArgoCdCm = true
293+ break
294+ }
279295 }
296+ }
280297
298+ if isFoundInArgoCdCm {
299+ var data map [string ]string
300+ // if the repo name has been updated then, create a new repo
301+ if cm != nil && cm .Data != nil {
302+ data , err = impl .updateRepoData (cm .Data , request )
303+ // if the repo name has been updated then, delete the previous repo
304+ if err != nil {
305+ impl .logger .Warnw (" config map update failed" , "err" , err )
306+ continue
307+ }
308+ if previousName != request .Name {
309+ data , err = impl .removeRepoData (cm .Data , previousName )
310+ }
311+ if err != nil {
312+ impl .logger .Warnw (" config map update failed" , "err" , err )
313+ continue
314+ }
315+ }
281316 cm .Data = data
282317 _ , err = impl .K8sUtil .UpdateConfigMap (impl .aCDAuthConfig .ACDConfigMapNamespace , cm , client )
283318 } else {
284- secretData := impl .CreateSecretDataForPrivateHelmChart (request )
319+ secretData := impl .CreateSecretDataForHelmChart (request , isPrivateChart )
285320 secret , err := impl .K8sUtil .GetSecret (impl .aCDAuthConfig .ACDConfigMapNamespace , previousName , client )
286321 if err != nil {
287322 impl .logger .Errorw ("error in fetching secret" , "err" , err )
@@ -380,23 +415,45 @@ func (impl *ChartRepositoryServiceImpl) DeleteChartRepo(request *ChartRepoDto) e
380415 retryCount := 0
381416 //request.Url = ""
382417
383- isPrivateChart := false
384- if len (chartRepo .UserName ) > 0 && len (chartRepo .Password ) > 0 {
385- isPrivateChart = true
386- }
387-
388418 for ! updateSuccess && retryCount < 3 {
389419 retryCount = retryCount + 1
390420
391- if ! isPrivateChart {
392- cm , err := impl .K8sUtil .GetConfigMap (impl .aCDAuthConfig .ACDConfigMapNamespace , impl .aCDAuthConfig .ACDConfigMapName , client )
421+ var isFoundInArgoCdCm bool
422+ cm , err := impl .K8sUtil .GetConfigMap (impl .aCDAuthConfig .ACDConfigMapNamespace , impl .aCDAuthConfig .ACDConfigMapName , client )
423+ if err != nil {
424+ return err
425+ }
426+ var repositories []* AcdConfigMapRepositoriesDto
427+ if cm != nil && cm .Data != nil {
428+ repoStr := cm .Data ["repositories" ]
429+ repoByte , err := yaml .YAMLToJSON ([]byte (repoStr ))
393430 if err != nil {
431+ impl .logger .Errorw ("error in json patch" , "err" , err )
394432 return err
395433 }
396- data , err := impl . removeRepoData ( cm . Data , request . Name )
434+ err = json . Unmarshal ( repoByte , & repositories )
397435 if err != nil {
398- impl .logger .Warnw (" config map update failed" , "err" , err )
399- continue
436+ impl .logger .Errorw ("error in unmarshal" , "err" , err )
437+ return err
438+ }
439+ for _ , repo := range repositories {
440+ if repo .Name == request .Name && repo .Url == request .Url {
441+ //chart repo is present in argocd-cm
442+ isFoundInArgoCdCm = true
443+ break
444+ }
445+ }
446+ }
447+
448+ if isFoundInArgoCdCm {
449+ var data map [string ]string
450+
451+ if cm != nil && cm .Data != nil {
452+ data , err = impl .removeRepoData (cm .Data , request .Name )
453+ if err != nil {
454+ impl .logger .Warnw (" config map update failed" , "err" , err )
455+ continue
456+ }
400457 }
401458 cm .Data = data
402459 _ , err = impl .K8sUtil .UpdateConfigMap (impl .aCDAuthConfig .ACDConfigMapNamespace , cm , client )
@@ -572,6 +629,10 @@ func (impl *ChartRepositoryServiceImpl) ValidateAndCreateChartRepo(request *Char
572629 if err != nil {
573630 return nil , err , validationResult
574631 }
632+ if chartRepo == nil && err == nil {
633+ //case when no entry for chart in chart_repo table and no need to trigger chart sync
634+ return nil , nil , validationResult
635+ }
575636
576637 // Trigger chart sync job, ignore error
577638 err = impl .TriggerChartSyncManual ()
0 commit comments