github.com/argoproj/argo-cd/v3@v3.2.1/util/notification/expression/repo/repo.go (about)

     1  package repo
     2  
     3  import (
     4  	"context"
     5  	"encoding/json"
     6  	"errors"
     7  	"net/url"
     8  	"regexp"
     9  	"strings"
    10  
    11  	service "github.com/argoproj/argo-cd/v3/util/notification/argocd"
    12  
    13  	"github.com/argoproj/argo-cd/v3/util/notification/expression/shared"
    14  
    15  	"github.com/argoproj/notifications-engine/pkg/util/text"
    16  	giturls "github.com/chainguard-dev/git-urls"
    17  	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
    18  
    19  	"github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1"
    20  )
    21  
    22  var gitSuffix = regexp.MustCompile(`\.git$`)
    23  
    24  func getApplication(obj *unstructured.Unstructured) (*v1alpha1.Application, error) {
    25  	data, err := json.Marshal(obj)
    26  	if err != nil {
    27  		return nil, err
    28  	}
    29  	application := &v1alpha1.Application{}
    30  	err = json.Unmarshal(data, application)
    31  	if err != nil {
    32  		return nil, err
    33  	}
    34  	return application, nil
    35  }
    36  
    37  func getAppDetails(un *unstructured.Unstructured, argocdService service.Service) (*shared.AppDetail, error) {
    38  	app, err := getApplication(un)
    39  	if err != nil {
    40  		return nil, err
    41  	}
    42  	appDetail, err := argocdService.GetAppDetails(context.Background(), app)
    43  	if err != nil {
    44  		return nil, err
    45  	}
    46  	return appDetail, nil
    47  }
    48  
    49  func getCommitMetadata(commitSHA string, app *unstructured.Unstructured, argocdService service.Service) (*shared.CommitMetadata, error) {
    50  	repoURL, ok, err := unstructured.NestedString(app.Object, "spec", "source", "repoURL")
    51  	if err != nil {
    52  		return nil, err
    53  	}
    54  	if !ok {
    55  		panic(errors.New("failed to get application source repo URL"))
    56  	}
    57  	project, ok, err := unstructured.NestedString(app.Object, "spec", "project")
    58  	if err != nil {
    59  		return nil, err
    60  	}
    61  	if !ok {
    62  		panic(errors.New("failed to get application project"))
    63  	}
    64  
    65  	meta, err := argocdService.GetCommitMetadata(context.Background(), repoURL, commitSHA, project)
    66  	if err != nil {
    67  		return nil, err
    68  	}
    69  	return meta, nil
    70  }
    71  
    72  func FullNameByRepoURL(rawURL string) string {
    73  	parsed, err := giturls.Parse(rawURL)
    74  	if err != nil {
    75  		panic(err)
    76  	}
    77  
    78  	path := gitSuffix.ReplaceAllString(parsed.Path, "")
    79  	if pathParts := text.SplitRemoveEmpty(path, "/"); len(pathParts) >= 2 {
    80  		return strings.Join(pathParts[:2], "/")
    81  	}
    82  
    83  	return path
    84  }
    85  
    86  func repoURLToHTTPS(rawURL string) string {
    87  	parsed, err := giturls.Parse(rawURL)
    88  	if err != nil {
    89  		panic(err)
    90  	}
    91  	parsed.Scheme = "https"
    92  	parsed.User = nil
    93  	return parsed.String()
    94  }
    95  
    96  func NewExprs(argocdService service.Service, app *unstructured.Unstructured) map[string]any {
    97  	return map[string]any{
    98  		"RepoURLToHTTPS":    repoURLToHTTPS,
    99  		"FullNameByRepoURL": FullNameByRepoURL,
   100  		"QueryEscape":       url.QueryEscape,
   101  		"GetCommitMetadata": func(commitSHA string) any {
   102  			meta, err := getCommitMetadata(commitSHA, app, argocdService)
   103  			if err != nil {
   104  				panic(err)
   105  			}
   106  
   107  			return *meta
   108  		},
   109  		"GetAppDetails": func() any {
   110  			appDetails, err := getAppDetails(app, argocdService)
   111  			if err != nil {
   112  				panic(err)
   113  			}
   114  
   115  			return *appDetails
   116  		},
   117  	}
   118  }