@@ -82,6 +82,7 @@ const (
8282 ApplicationTypeUnsupported ApplicationType = 0
8383 ApplicationTypeHelm ApplicationType = 1
8484 ApplicationTypeKustomize ApplicationType = 2
85+ ApplicationTypePlugin ApplicationType = 3
8586)
8687
8788// Basic wrapper struct for ArgoCD client options
@@ -478,6 +479,139 @@ func SetKustomizeImage(app *v1alpha1.Application, newImage *image.ContainerImage
478479 return nil
479480}
480481
482+ // SetPluginImage sets the image parameters for a Plugin type application
483+ func SetPluginImage (app * v1alpha1.Application , newImage * image.ContainerImage ) error {
484+ if appType := getApplicationType (app ); appType != ApplicationTypePlugin {
485+ return fmt .Errorf ("cannot set Helm arguments on non-Plugin application" )
486+ }
487+
488+ appName := app .GetName ()
489+
490+ var hpImageName , hpImageTag , hpImageSpec string
491+
492+ hpImageSpec = newImage .GetParameterHelmImageSpec (app .Annotations )
493+ hpImageName = newImage .GetParameterHelmImageName (app .Annotations )
494+ hpImageTag = newImage .GetParameterHelmImageTag (app .Annotations )
495+
496+ if hpImageSpec == "" {
497+ if hpImageName == "" {
498+ hpImageName = common .DefaultHelmImageName
499+ }
500+ if hpImageTag == "" {
501+ hpImageTag = common .DefaultHelmImageTag
502+ }
503+ }
504+
505+ log .WithContext ().
506+ AddField ("application" , appName ).
507+ AddField ("image" , newImage .GetFullNameWithoutTag ()).
508+ Debugf ("target parameters: image-spec=%s image-name=%s, image-tag=%s" , hpImageSpec , hpImageName , hpImageTag )
509+
510+ // Initialize a map to hold the merged parameters
511+ mergeParams := make (map [string ]string )
512+
513+ // If image-spec is set, it overrides any image-name and image-tag parameters
514+ if hpImageSpec != "" {
515+ mergeParams [hpImageSpec ] = newImage .GetFullNameWithTag ()
516+ } else {
517+ if hpImageName != "" {
518+ mergeParams [hpImageName ] = newImage .GetFullNameWithoutTag ()
519+ }
520+ if hpImageTag != "" {
521+ mergeParams [hpImageTag ] = newImage .GetTagWithDigest ()
522+ }
523+ }
524+
525+ if app .Spec .Source .Plugin == nil {
526+ app .Spec .Source .Plugin = & v1alpha1.ApplicationSourcePlugin {}
527+ }
528+
529+ if app .Spec .Source .Plugin .Env == nil {
530+ app .Spec .Source .Plugin .Env = make ([]* v1alpha1.EnvEntry , 0 )
531+ }
532+
533+ // Retrieve the existing HELM_ARGS value
534+ helmArgs := ""
535+ for _ , env := range app .Spec .Source .Plugin .Env {
536+ if env .Name == common .DefaultPluginEnvVarName {
537+ helmArgs = env .Value
538+ break
539+ }
540+ }
541+
542+ // Parse the existing HELM_ARGS into parameters and other arguments
543+ existingParams , otherArgs := parseHelmArgs (helmArgs )
544+
545+ // Merge the new parameters with the existing ones
546+ for key , value := range mergeParams {
547+ existingValue , exists := existingParams [key ]
548+ if ! exists || existingValue != value {
549+ existingParams [key ] = value
550+ }
551+ }
552+
553+ // Build the new HELM_ARGS string
554+ newHelmArgs := buildHelmArgs (existingParams , otherArgs )
555+
556+ // If there are no changes in HELM_ARGS, return early
557+ if newHelmArgs == helmArgs {
558+ return nil
559+ }
560+
561+ // Update the HELM_ARGS environment variable
562+ found := false
563+ for _ , env := range app .Spec .Source .Plugin .Env {
564+ if env .Name == common .DefaultPluginEnvVarName {
565+ env .Value = newHelmArgs
566+ found = true
567+ break
568+ }
569+ }
570+
571+ // If HELM_ARGS was not found, add it to the environment variables
572+ if ! found {
573+ app .Spec .Source .Plugin .Env = append (app .Spec .Source .Plugin .Env , & v1alpha1.EnvEntry {Name : common .DefaultPluginEnvVarName , Value : newHelmArgs })
574+ }
575+
576+ return nil
577+ }
578+
579+ // parseHelmArgs parses a HELM_ARGS string into a map of parameters and a slice of other arguments
580+ func parseHelmArgs (helmArgs string ) (map [string ]string , []string ) {
581+ params := make (map [string ]string ) // Map to hold --set parameters
582+ var otherArgs []string // Slice to hold other arguments
583+
584+ // Split the HELM_ARGS string into individual arguments
585+ args := strings .Fields (helmArgs )
586+ for i := 0 ; i < len (args ); i ++ {
587+ // Check if the argument is a --set parameter
588+ if args [i ] == "--set" && i + 1 < len (args ) {
589+ // Split the --set parameter into key and value
590+ parts := strings .SplitN (args [i + 1 ], "=" , 2 )
591+ if len (parts ) == 2 {
592+ // Add the key and value to the params map
593+ params [parts [0 ]] = parts [1 ]
594+ }
595+ i ++ // Skip the next argument as it has been processed
596+ } else {
597+ // Add non --set arguments to otherArgs slice
598+ otherArgs = append (otherArgs , args [i ])
599+ }
600+ }
601+ return params , otherArgs // Return the parsed parameters and other arguments
602+ }
603+
604+ // buildHelmArgs constructs a HELM_ARGS string from a map of parameters and a slice of other arguments
605+ func buildHelmArgs (params map [string ]string , otherArgs []string ) string {
606+ args := otherArgs // Start with other arguments
607+ for key , value := range params {
608+ // Append each --set parameter to the arguments
609+ args = append (args , fmt .Sprintf ("--set %s=%s" , key , value ))
610+ }
611+ // Join all arguments into a single HELM_ARGS string
612+ return strings .Join (args , " " )
613+ }
614+
481615// GetImagesFromApplication returns the list of known images for the given application
482616func GetImagesFromApplication (app * v1alpha1.Application ) image.ContainerImageList {
483617 images := make (image.ContainerImageList , 0 )
@@ -556,6 +690,8 @@ func getApplicationType(app *v1alpha1.Application) ApplicationType {
556690 return ApplicationTypeKustomize
557691 } else if sourceType == v1alpha1 .ApplicationSourceTypeHelm {
558692 return ApplicationTypeHelm
693+ } else if sourceType == v1alpha1 .ApplicationSourceTypePlugin {
694+ return ApplicationTypePlugin
559695 } else {
560696 return ApplicationTypeUnsupported
561697 }
@@ -609,6 +745,8 @@ func (a ApplicationType) String() string {
609745 return "Kustomize"
610746 case ApplicationTypeHelm :
611747 return "Helm"
748+ case ApplicationTypePlugin :
749+ return "Plugin"
612750 case ApplicationTypeUnsupported :
613751 return "Unsupported"
614752 default :
0 commit comments