From d0e21353ecf268704555d3cde43568c22e5e78bb Mon Sep 17 00:00:00 2001 From: pashavictorovich Date: Mon, 6 Dec 2021 15:01:59 +0200 Subject: [PATCH 1/3] move projects Signed-off-by: pashavictorovich --- util/argo/argo.go | 123 -------------------------------------- util/argo/project.go | 137 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 137 insertions(+), 123 deletions(-) create mode 100644 util/argo/project.go diff --git a/util/argo/argo.go b/util/argo/argo.go index 9c208b4744f45..b42195aeb6251 100644 --- a/util/argo/argo.go +++ b/util/argo/argo.go @@ -43,26 +43,6 @@ func FormatAppConditions(conditions []argoappv1.ApplicationCondition) string { return strings.Join(formattedConditions, ";") } -// FilterByProjects returns applications which belongs to the specified project -func FilterByProjects(apps []argoappv1.Application, projects []string) []argoappv1.Application { - if len(projects) == 0 { - return apps - } - projectsMap := make(map[string]bool) - for i := range projects { - projectsMap[projects[i]] = true - } - items := make([]argoappv1.Application, 0) - for i := 0; i < len(apps); i++ { - a := apps[i] - if _, ok := projectsMap[a.Spec.GetProject()]; ok { - items = append(items, a) - } - } - return items - -} - // FilterByRepo returns an application func FilterByRepo(apps []argoappv1.Application, repo string) []argoappv1.Application { if repo == "" { @@ -441,35 +421,6 @@ func GetAppProjectWithScopedResources(name string, projLister applicationsv1.App } -// GetAppProjectByName returns a project from an application based on name -func GetAppProjectByName(name string, projLister applicationsv1.AppProjectLister, ns string, settingsManager *settings.SettingsManager, db db.ArgoDB, ctx context.Context) (*argoappv1.AppProject, error) { - projOrig, err := projLister.AppProjects(ns).Get(name) - if err != nil { - return nil, err - } - project := projOrig.DeepCopy() - repos := retrieveScopedRepositories(name, db, ctx) - for _, repo := range repos { - project.Spec.SourceRepos = append(project.Spec.SourceRepos, repo.Repo) - } - clusters := retrieveScopedClusters(name, db, ctx) - for _, cluster := range clusters { - if len(cluster.Namespaces) == 0 { - project.Spec.Destinations = append(project.Spec.Destinations, argoappv1.ApplicationDestination{Server: cluster.Server, Namespace: "*"}) - } else { - for _, ns := range cluster.Namespaces { - project.Spec.Destinations = append(project.Spec.Destinations, argoappv1.ApplicationDestination{Server: cluster.Server, Namespace: ns}) - } - } - } - return GetAppVirtualProject(project, projLister, settingsManager) -} - -// GetAppProject returns a project from an application -func GetAppProject(spec *argoappv1.ApplicationSpec, projLister applicationsv1.AppProjectLister, ns string, settingsManager *settings.SettingsManager, db db.ArgoDB, ctx context.Context) (*argoappv1.AppProject, error) { - return GetAppProjectByName(spec.GetProject(), projLister, ns, settingsManager, db, ctx) -} - // verifyGenerateManifests verifies a repo path can generate manifests func verifyGenerateManifests( ctx context.Context, @@ -639,80 +590,6 @@ func getDestinationServer(ctx context.Context, db db.ArgoDB, clusterName string) return servers[0], nil } -func GetGlobalProjects(proj *argoappv1.AppProject, projLister applicationsv1.AppProjectLister, settingsManager *settings.SettingsManager) []*argoappv1.AppProject { - gps, err := settingsManager.GetGlobalProjectsSettings() - globalProjects := make([]*argoappv1.AppProject, 0) - - if err != nil { - log.Warnf("Failed to get global project settings: %v", err) - return globalProjects - } - - for _, gp := range gps { - //The project itself is not its own the global project - if proj.Name == gp.ProjectName { - continue - } - - selector, err := metav1.LabelSelectorAsSelector(&gp.LabelSelector) - if err != nil { - break - } - //Get projects which match the label selector, then see if proj is a match - projList, err := projLister.AppProjects(proj.Namespace).List(selector) - if err != nil { - break - } - var matchMe bool - for _, item := range projList { - if item.Name == proj.Name { - matchMe = true - break - } - } - if !matchMe { - continue - } - //If proj is a match for this global project setting, then it is its global project - globalProj, err := projLister.AppProjects(proj.Namespace).Get(gp.ProjectName) - if err != nil { - break - } - globalProjects = append(globalProjects, globalProj) - - } - return globalProjects -} - -func GetAppVirtualProject(proj *argoappv1.AppProject, projLister applicationsv1.AppProjectLister, settingsManager *settings.SettingsManager) (*argoappv1.AppProject, error) { - virtualProj := proj.DeepCopy() - globalProjects := GetGlobalProjects(proj, projLister, settingsManager) - - for _, gp := range globalProjects { - virtualProj = mergeVirtualProject(virtualProj, gp) - } - return virtualProj, nil -} - -func mergeVirtualProject(proj *argoappv1.AppProject, globalProj *argoappv1.AppProject) *argoappv1.AppProject { - if globalProj == nil { - return proj - } - proj.Spec.ClusterResourceWhitelist = append(proj.Spec.ClusterResourceWhitelist, globalProj.Spec.ClusterResourceWhitelist...) - proj.Spec.ClusterResourceBlacklist = append(proj.Spec.ClusterResourceBlacklist, globalProj.Spec.ClusterResourceBlacklist...) - - proj.Spec.NamespaceResourceWhitelist = append(proj.Spec.NamespaceResourceWhitelist, globalProj.Spec.NamespaceResourceWhitelist...) - proj.Spec.NamespaceResourceBlacklist = append(proj.Spec.NamespaceResourceBlacklist, globalProj.Spec.NamespaceResourceBlacklist...) - - proj.Spec.SyncWindows = append(proj.Spec.SyncWindows, globalProj.Spec.SyncWindows...) - - proj.Spec.SourceRepos = append(proj.Spec.SourceRepos, globalProj.Spec.SourceRepos...) - - proj.Spec.Destinations = append(proj.Spec.Destinations, globalProj.Spec.Destinations...) - - return proj -} - func GenerateSpecIsDifferentErrorMessage(entity string, a, b interface{}) string { basicMsg := fmt.Sprintf("existing %s spec is different; use upsert flag to force update", entity) difference, _ := GetDifferentPathsBetweenStructs(a, b) diff --git a/util/argo/project.go b/util/argo/project.go new file mode 100644 index 0000000000000..06ad8f8ac9dc3 --- /dev/null +++ b/util/argo/project.go @@ -0,0 +1,137 @@ +package argo + +import ( + "context" + + "github.com/prometheus/common/log" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + argoappv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + applicationsv1 "github.com/argoproj/argo-cd/v2/pkg/client/listers/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/util/db" + "github.com/argoproj/argo-cd/v2/util/settings" +) + +// FilterByProjects returns applications which belongs to the specified project +func FilterByProjects(apps []argoappv1.Application, projects []string) []argoappv1.Application { + if len(projects) == 0 { + return apps + } + projectsMap := make(map[string]bool) + for i := range projects { + projectsMap[projects[i]] = true + } + items := make([]argoappv1.Application, 0) + for i := 0; i < len(apps); i++ { + a := apps[i] + if _, ok := projectsMap[a.Spec.GetProject()]; ok { + items = append(items, a) + } + } + return items + +} + +// GetAppProjectByName returns a project from an application based on name +func GetAppProjectByName(name string, projLister applicationsv1.AppProjectLister, ns string, settingsManager *settings.SettingsManager, db db.ArgoDB, ctx context.Context) (*argoappv1.AppProject, error) { + projOrig, err := projLister.AppProjects(ns).Get(name) + if err != nil { + return nil, err + } + project := projOrig.DeepCopy() + repos := retrieveScopedRepositories(name, db, ctx) + for _, repo := range repos { + project.Spec.SourceRepos = append(project.Spec.SourceRepos, repo.Repo) + } + clusters := retrieveScopedClusters(name, db, ctx) + for _, cluster := range clusters { + if len(cluster.Namespaces) == 0 { + project.Spec.Destinations = append(project.Spec.Destinations, argoappv1.ApplicationDestination{Server: cluster.Server, Namespace: "*"}) + } else { + for _, ns := range cluster.Namespaces { + project.Spec.Destinations = append(project.Spec.Destinations, argoappv1.ApplicationDestination{Server: cluster.Server, Namespace: ns}) + } + } + } + return GetAppVirtualProject(project, projLister, settingsManager) +} + +func GetAppVirtualProject(proj *argoappv1.AppProject, projLister applicationsv1.AppProjectLister, settingsManager *settings.SettingsManager) (*argoappv1.AppProject, error) { + virtualProj := proj.DeepCopy() + globalProjects := GetGlobalProjects(proj, projLister, settingsManager) + + for _, gp := range globalProjects { + virtualProj = mergeVirtualProject(virtualProj, gp) + } + return virtualProj, nil +} + +// GetAppProject returns a project from an application +func GetAppProject(spec *argoappv1.ApplicationSpec, projLister applicationsv1.AppProjectLister, ns string, settingsManager *settings.SettingsManager, db db.ArgoDB, ctx context.Context) (*argoappv1.AppProject, error) { + return GetAppProjectByName(spec.GetProject(), projLister, ns, settingsManager, db, ctx) +} + +func GetGlobalProjects(proj *argoappv1.AppProject, projLister applicationsv1.AppProjectLister, settingsManager *settings.SettingsManager) []*argoappv1.AppProject { + gps, err := settingsManager.GetGlobalProjectsSettings() + globalProjects := make([]*argoappv1.AppProject, 0) + + if err != nil { + log.Warnf("Failed to get global project settings: %v", err) + return globalProjects + } + + for _, gp := range gps { + //The project itself is not its own the global project + if proj.Name == gp.ProjectName { + continue + } + + selector, err := metav1.LabelSelectorAsSelector(&gp.LabelSelector) + if err != nil { + break + } + //Get projects which match the label selector, then see if proj is a match + projList, err := projLister.AppProjects(proj.Namespace).List(selector) + if err != nil { + break + } + var matchMe bool + for _, item := range projList { + if item.Name == proj.Name { + matchMe = true + break + } + } + if !matchMe { + continue + } + //If proj is a match for this global project setting, then it is its global project + globalProj, err := projLister.AppProjects(proj.Namespace).Get(gp.ProjectName) + if err != nil { + break + } + globalProjects = append(globalProjects, globalProj) + + } + return globalProjects +} + +func mergeVirtualProject(proj *argoappv1.AppProject, globalProj *argoappv1.AppProject) *argoappv1.AppProject { + if globalProj == nil { + return proj + } + proj.Spec.ClusterResourceWhitelist = append(proj.Spec.ClusterResourceWhitelist, globalProj.Spec.ClusterResourceWhitelist...) + proj.Spec.ClusterResourceBlacklist = append(proj.Spec.ClusterResourceBlacklist, globalProj.Spec.ClusterResourceBlacklist...) + + proj.Spec.NamespaceResourceWhitelist = append(proj.Spec.NamespaceResourceWhitelist, globalProj.Spec.NamespaceResourceWhitelist...) + proj.Spec.NamespaceResourceBlacklist = append(proj.Spec.NamespaceResourceBlacklist, globalProj.Spec.NamespaceResourceBlacklist...) + + proj.Spec.SyncWindows = append(proj.Spec.SyncWindows, globalProj.Spec.SyncWindows...) + + proj.Spec.SourceRepos = append(proj.Spec.SourceRepos, globalProj.Spec.SourceRepos...) + + proj.Spec.Destinations = append(proj.Spec.Destinations, globalProj.Spec.Destinations...) + + return proj +} From 7a82176b539d047c4e221bab24027face455d01a Mon Sep 17 00:00:00 2001 From: pashavictorovich Date: Mon, 6 Dec 2021 15:03:08 +0200 Subject: [PATCH 2/3] Revert "move projects" This reverts commit d0e21353 Signed-off-by: pashavictorovich --- util/argo/argo.go | 123 ++++++++++++++++++++++++++++++++++++++ util/argo/project.go | 137 ------------------------------------------- 2 files changed, 123 insertions(+), 137 deletions(-) delete mode 100644 util/argo/project.go diff --git a/util/argo/argo.go b/util/argo/argo.go index b42195aeb6251..9c208b4744f45 100644 --- a/util/argo/argo.go +++ b/util/argo/argo.go @@ -43,6 +43,26 @@ func FormatAppConditions(conditions []argoappv1.ApplicationCondition) string { return strings.Join(formattedConditions, ";") } +// FilterByProjects returns applications which belongs to the specified project +func FilterByProjects(apps []argoappv1.Application, projects []string) []argoappv1.Application { + if len(projects) == 0 { + return apps + } + projectsMap := make(map[string]bool) + for i := range projects { + projectsMap[projects[i]] = true + } + items := make([]argoappv1.Application, 0) + for i := 0; i < len(apps); i++ { + a := apps[i] + if _, ok := projectsMap[a.Spec.GetProject()]; ok { + items = append(items, a) + } + } + return items + +} + // FilterByRepo returns an application func FilterByRepo(apps []argoappv1.Application, repo string) []argoappv1.Application { if repo == "" { @@ -421,6 +441,35 @@ func GetAppProjectWithScopedResources(name string, projLister applicationsv1.App } +// GetAppProjectByName returns a project from an application based on name +func GetAppProjectByName(name string, projLister applicationsv1.AppProjectLister, ns string, settingsManager *settings.SettingsManager, db db.ArgoDB, ctx context.Context) (*argoappv1.AppProject, error) { + projOrig, err := projLister.AppProjects(ns).Get(name) + if err != nil { + return nil, err + } + project := projOrig.DeepCopy() + repos := retrieveScopedRepositories(name, db, ctx) + for _, repo := range repos { + project.Spec.SourceRepos = append(project.Spec.SourceRepos, repo.Repo) + } + clusters := retrieveScopedClusters(name, db, ctx) + for _, cluster := range clusters { + if len(cluster.Namespaces) == 0 { + project.Spec.Destinations = append(project.Spec.Destinations, argoappv1.ApplicationDestination{Server: cluster.Server, Namespace: "*"}) + } else { + for _, ns := range cluster.Namespaces { + project.Spec.Destinations = append(project.Spec.Destinations, argoappv1.ApplicationDestination{Server: cluster.Server, Namespace: ns}) + } + } + } + return GetAppVirtualProject(project, projLister, settingsManager) +} + +// GetAppProject returns a project from an application +func GetAppProject(spec *argoappv1.ApplicationSpec, projLister applicationsv1.AppProjectLister, ns string, settingsManager *settings.SettingsManager, db db.ArgoDB, ctx context.Context) (*argoappv1.AppProject, error) { + return GetAppProjectByName(spec.GetProject(), projLister, ns, settingsManager, db, ctx) +} + // verifyGenerateManifests verifies a repo path can generate manifests func verifyGenerateManifests( ctx context.Context, @@ -590,6 +639,80 @@ func getDestinationServer(ctx context.Context, db db.ArgoDB, clusterName string) return servers[0], nil } +func GetGlobalProjects(proj *argoappv1.AppProject, projLister applicationsv1.AppProjectLister, settingsManager *settings.SettingsManager) []*argoappv1.AppProject { + gps, err := settingsManager.GetGlobalProjectsSettings() + globalProjects := make([]*argoappv1.AppProject, 0) + + if err != nil { + log.Warnf("Failed to get global project settings: %v", err) + return globalProjects + } + + for _, gp := range gps { + //The project itself is not its own the global project + if proj.Name == gp.ProjectName { + continue + } + + selector, err := metav1.LabelSelectorAsSelector(&gp.LabelSelector) + if err != nil { + break + } + //Get projects which match the label selector, then see if proj is a match + projList, err := projLister.AppProjects(proj.Namespace).List(selector) + if err != nil { + break + } + var matchMe bool + for _, item := range projList { + if item.Name == proj.Name { + matchMe = true + break + } + } + if !matchMe { + continue + } + //If proj is a match for this global project setting, then it is its global project + globalProj, err := projLister.AppProjects(proj.Namespace).Get(gp.ProjectName) + if err != nil { + break + } + globalProjects = append(globalProjects, globalProj) + + } + return globalProjects +} + +func GetAppVirtualProject(proj *argoappv1.AppProject, projLister applicationsv1.AppProjectLister, settingsManager *settings.SettingsManager) (*argoappv1.AppProject, error) { + virtualProj := proj.DeepCopy() + globalProjects := GetGlobalProjects(proj, projLister, settingsManager) + + for _, gp := range globalProjects { + virtualProj = mergeVirtualProject(virtualProj, gp) + } + return virtualProj, nil +} + +func mergeVirtualProject(proj *argoappv1.AppProject, globalProj *argoappv1.AppProject) *argoappv1.AppProject { + if globalProj == nil { + return proj + } + proj.Spec.ClusterResourceWhitelist = append(proj.Spec.ClusterResourceWhitelist, globalProj.Spec.ClusterResourceWhitelist...) + proj.Spec.ClusterResourceBlacklist = append(proj.Spec.ClusterResourceBlacklist, globalProj.Spec.ClusterResourceBlacklist...) + + proj.Spec.NamespaceResourceWhitelist = append(proj.Spec.NamespaceResourceWhitelist, globalProj.Spec.NamespaceResourceWhitelist...) + proj.Spec.NamespaceResourceBlacklist = append(proj.Spec.NamespaceResourceBlacklist, globalProj.Spec.NamespaceResourceBlacklist...) + + proj.Spec.SyncWindows = append(proj.Spec.SyncWindows, globalProj.Spec.SyncWindows...) + + proj.Spec.SourceRepos = append(proj.Spec.SourceRepos, globalProj.Spec.SourceRepos...) + + proj.Spec.Destinations = append(proj.Spec.Destinations, globalProj.Spec.Destinations...) + + return proj +} + func GenerateSpecIsDifferentErrorMessage(entity string, a, b interface{}) string { basicMsg := fmt.Sprintf("existing %s spec is different; use upsert flag to force update", entity) difference, _ := GetDifferentPathsBetweenStructs(a, b) diff --git a/util/argo/project.go b/util/argo/project.go deleted file mode 100644 index 06ad8f8ac9dc3..0000000000000 --- a/util/argo/project.go +++ /dev/null @@ -1,137 +0,0 @@ -package argo - -import ( - "context" - - "github.com/prometheus/common/log" - - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - - argoappv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" - applicationsv1 "github.com/argoproj/argo-cd/v2/pkg/client/listers/application/v1alpha1" - "github.com/argoproj/argo-cd/v2/util/db" - "github.com/argoproj/argo-cd/v2/util/settings" -) - -// FilterByProjects returns applications which belongs to the specified project -func FilterByProjects(apps []argoappv1.Application, projects []string) []argoappv1.Application { - if len(projects) == 0 { - return apps - } - projectsMap := make(map[string]bool) - for i := range projects { - projectsMap[projects[i]] = true - } - items := make([]argoappv1.Application, 0) - for i := 0; i < len(apps); i++ { - a := apps[i] - if _, ok := projectsMap[a.Spec.GetProject()]; ok { - items = append(items, a) - } - } - return items - -} - -// GetAppProjectByName returns a project from an application based on name -func GetAppProjectByName(name string, projLister applicationsv1.AppProjectLister, ns string, settingsManager *settings.SettingsManager, db db.ArgoDB, ctx context.Context) (*argoappv1.AppProject, error) { - projOrig, err := projLister.AppProjects(ns).Get(name) - if err != nil { - return nil, err - } - project := projOrig.DeepCopy() - repos := retrieveScopedRepositories(name, db, ctx) - for _, repo := range repos { - project.Spec.SourceRepos = append(project.Spec.SourceRepos, repo.Repo) - } - clusters := retrieveScopedClusters(name, db, ctx) - for _, cluster := range clusters { - if len(cluster.Namespaces) == 0 { - project.Spec.Destinations = append(project.Spec.Destinations, argoappv1.ApplicationDestination{Server: cluster.Server, Namespace: "*"}) - } else { - for _, ns := range cluster.Namespaces { - project.Spec.Destinations = append(project.Spec.Destinations, argoappv1.ApplicationDestination{Server: cluster.Server, Namespace: ns}) - } - } - } - return GetAppVirtualProject(project, projLister, settingsManager) -} - -func GetAppVirtualProject(proj *argoappv1.AppProject, projLister applicationsv1.AppProjectLister, settingsManager *settings.SettingsManager) (*argoappv1.AppProject, error) { - virtualProj := proj.DeepCopy() - globalProjects := GetGlobalProjects(proj, projLister, settingsManager) - - for _, gp := range globalProjects { - virtualProj = mergeVirtualProject(virtualProj, gp) - } - return virtualProj, nil -} - -// GetAppProject returns a project from an application -func GetAppProject(spec *argoappv1.ApplicationSpec, projLister applicationsv1.AppProjectLister, ns string, settingsManager *settings.SettingsManager, db db.ArgoDB, ctx context.Context) (*argoappv1.AppProject, error) { - return GetAppProjectByName(spec.GetProject(), projLister, ns, settingsManager, db, ctx) -} - -func GetGlobalProjects(proj *argoappv1.AppProject, projLister applicationsv1.AppProjectLister, settingsManager *settings.SettingsManager) []*argoappv1.AppProject { - gps, err := settingsManager.GetGlobalProjectsSettings() - globalProjects := make([]*argoappv1.AppProject, 0) - - if err != nil { - log.Warnf("Failed to get global project settings: %v", err) - return globalProjects - } - - for _, gp := range gps { - //The project itself is not its own the global project - if proj.Name == gp.ProjectName { - continue - } - - selector, err := metav1.LabelSelectorAsSelector(&gp.LabelSelector) - if err != nil { - break - } - //Get projects which match the label selector, then see if proj is a match - projList, err := projLister.AppProjects(proj.Namespace).List(selector) - if err != nil { - break - } - var matchMe bool - for _, item := range projList { - if item.Name == proj.Name { - matchMe = true - break - } - } - if !matchMe { - continue - } - //If proj is a match for this global project setting, then it is its global project - globalProj, err := projLister.AppProjects(proj.Namespace).Get(gp.ProjectName) - if err != nil { - break - } - globalProjects = append(globalProjects, globalProj) - - } - return globalProjects -} - -func mergeVirtualProject(proj *argoappv1.AppProject, globalProj *argoappv1.AppProject) *argoappv1.AppProject { - if globalProj == nil { - return proj - } - proj.Spec.ClusterResourceWhitelist = append(proj.Spec.ClusterResourceWhitelist, globalProj.Spec.ClusterResourceWhitelist...) - proj.Spec.ClusterResourceBlacklist = append(proj.Spec.ClusterResourceBlacklist, globalProj.Spec.ClusterResourceBlacklist...) - - proj.Spec.NamespaceResourceWhitelist = append(proj.Spec.NamespaceResourceWhitelist, globalProj.Spec.NamespaceResourceWhitelist...) - proj.Spec.NamespaceResourceBlacklist = append(proj.Spec.NamespaceResourceBlacklist, globalProj.Spec.NamespaceResourceBlacklist...) - - proj.Spec.SyncWindows = append(proj.Spec.SyncWindows, globalProj.Spec.SyncWindows...) - - proj.Spec.SourceRepos = append(proj.Spec.SourceRepos, globalProj.Spec.SourceRepos...) - - proj.Spec.Destinations = append(proj.Spec.Destinations, globalProj.Spec.Destinations...) - - return proj -} From cae047ae5df95a66bc03d3231a47319e5f3a4dbe Mon Sep 17 00:00:00 2001 From: pashavictorovich Date: Mon, 6 Dec 2021 15:04:08 +0200 Subject: [PATCH 3/3] separate projects Signed-off-by: pashavictorovich --- util/argo/argo.go | 123 -------------------------------------- util/argo/project.go | 137 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 137 insertions(+), 123 deletions(-) create mode 100644 util/argo/project.go diff --git a/util/argo/argo.go b/util/argo/argo.go index 9c208b4744f45..b42195aeb6251 100644 --- a/util/argo/argo.go +++ b/util/argo/argo.go @@ -43,26 +43,6 @@ func FormatAppConditions(conditions []argoappv1.ApplicationCondition) string { return strings.Join(formattedConditions, ";") } -// FilterByProjects returns applications which belongs to the specified project -func FilterByProjects(apps []argoappv1.Application, projects []string) []argoappv1.Application { - if len(projects) == 0 { - return apps - } - projectsMap := make(map[string]bool) - for i := range projects { - projectsMap[projects[i]] = true - } - items := make([]argoappv1.Application, 0) - for i := 0; i < len(apps); i++ { - a := apps[i] - if _, ok := projectsMap[a.Spec.GetProject()]; ok { - items = append(items, a) - } - } - return items - -} - // FilterByRepo returns an application func FilterByRepo(apps []argoappv1.Application, repo string) []argoappv1.Application { if repo == "" { @@ -441,35 +421,6 @@ func GetAppProjectWithScopedResources(name string, projLister applicationsv1.App } -// GetAppProjectByName returns a project from an application based on name -func GetAppProjectByName(name string, projLister applicationsv1.AppProjectLister, ns string, settingsManager *settings.SettingsManager, db db.ArgoDB, ctx context.Context) (*argoappv1.AppProject, error) { - projOrig, err := projLister.AppProjects(ns).Get(name) - if err != nil { - return nil, err - } - project := projOrig.DeepCopy() - repos := retrieveScopedRepositories(name, db, ctx) - for _, repo := range repos { - project.Spec.SourceRepos = append(project.Spec.SourceRepos, repo.Repo) - } - clusters := retrieveScopedClusters(name, db, ctx) - for _, cluster := range clusters { - if len(cluster.Namespaces) == 0 { - project.Spec.Destinations = append(project.Spec.Destinations, argoappv1.ApplicationDestination{Server: cluster.Server, Namespace: "*"}) - } else { - for _, ns := range cluster.Namespaces { - project.Spec.Destinations = append(project.Spec.Destinations, argoappv1.ApplicationDestination{Server: cluster.Server, Namespace: ns}) - } - } - } - return GetAppVirtualProject(project, projLister, settingsManager) -} - -// GetAppProject returns a project from an application -func GetAppProject(spec *argoappv1.ApplicationSpec, projLister applicationsv1.AppProjectLister, ns string, settingsManager *settings.SettingsManager, db db.ArgoDB, ctx context.Context) (*argoappv1.AppProject, error) { - return GetAppProjectByName(spec.GetProject(), projLister, ns, settingsManager, db, ctx) -} - // verifyGenerateManifests verifies a repo path can generate manifests func verifyGenerateManifests( ctx context.Context, @@ -639,80 +590,6 @@ func getDestinationServer(ctx context.Context, db db.ArgoDB, clusterName string) return servers[0], nil } -func GetGlobalProjects(proj *argoappv1.AppProject, projLister applicationsv1.AppProjectLister, settingsManager *settings.SettingsManager) []*argoappv1.AppProject { - gps, err := settingsManager.GetGlobalProjectsSettings() - globalProjects := make([]*argoappv1.AppProject, 0) - - if err != nil { - log.Warnf("Failed to get global project settings: %v", err) - return globalProjects - } - - for _, gp := range gps { - //The project itself is not its own the global project - if proj.Name == gp.ProjectName { - continue - } - - selector, err := metav1.LabelSelectorAsSelector(&gp.LabelSelector) - if err != nil { - break - } - //Get projects which match the label selector, then see if proj is a match - projList, err := projLister.AppProjects(proj.Namespace).List(selector) - if err != nil { - break - } - var matchMe bool - for _, item := range projList { - if item.Name == proj.Name { - matchMe = true - break - } - } - if !matchMe { - continue - } - //If proj is a match for this global project setting, then it is its global project - globalProj, err := projLister.AppProjects(proj.Namespace).Get(gp.ProjectName) - if err != nil { - break - } - globalProjects = append(globalProjects, globalProj) - - } - return globalProjects -} - -func GetAppVirtualProject(proj *argoappv1.AppProject, projLister applicationsv1.AppProjectLister, settingsManager *settings.SettingsManager) (*argoappv1.AppProject, error) { - virtualProj := proj.DeepCopy() - globalProjects := GetGlobalProjects(proj, projLister, settingsManager) - - for _, gp := range globalProjects { - virtualProj = mergeVirtualProject(virtualProj, gp) - } - return virtualProj, nil -} - -func mergeVirtualProject(proj *argoappv1.AppProject, globalProj *argoappv1.AppProject) *argoappv1.AppProject { - if globalProj == nil { - return proj - } - proj.Spec.ClusterResourceWhitelist = append(proj.Spec.ClusterResourceWhitelist, globalProj.Spec.ClusterResourceWhitelist...) - proj.Spec.ClusterResourceBlacklist = append(proj.Spec.ClusterResourceBlacklist, globalProj.Spec.ClusterResourceBlacklist...) - - proj.Spec.NamespaceResourceWhitelist = append(proj.Spec.NamespaceResourceWhitelist, globalProj.Spec.NamespaceResourceWhitelist...) - proj.Spec.NamespaceResourceBlacklist = append(proj.Spec.NamespaceResourceBlacklist, globalProj.Spec.NamespaceResourceBlacklist...) - - proj.Spec.SyncWindows = append(proj.Spec.SyncWindows, globalProj.Spec.SyncWindows...) - - proj.Spec.SourceRepos = append(proj.Spec.SourceRepos, globalProj.Spec.SourceRepos...) - - proj.Spec.Destinations = append(proj.Spec.Destinations, globalProj.Spec.Destinations...) - - return proj -} - func GenerateSpecIsDifferentErrorMessage(entity string, a, b interface{}) string { basicMsg := fmt.Sprintf("existing %s spec is different; use upsert flag to force update", entity) difference, _ := GetDifferentPathsBetweenStructs(a, b) diff --git a/util/argo/project.go b/util/argo/project.go new file mode 100644 index 0000000000000..06ad8f8ac9dc3 --- /dev/null +++ b/util/argo/project.go @@ -0,0 +1,137 @@ +package argo + +import ( + "context" + + "github.com/prometheus/common/log" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + argoappv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + applicationsv1 "github.com/argoproj/argo-cd/v2/pkg/client/listers/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/util/db" + "github.com/argoproj/argo-cd/v2/util/settings" +) + +// FilterByProjects returns applications which belongs to the specified project +func FilterByProjects(apps []argoappv1.Application, projects []string) []argoappv1.Application { + if len(projects) == 0 { + return apps + } + projectsMap := make(map[string]bool) + for i := range projects { + projectsMap[projects[i]] = true + } + items := make([]argoappv1.Application, 0) + for i := 0; i < len(apps); i++ { + a := apps[i] + if _, ok := projectsMap[a.Spec.GetProject()]; ok { + items = append(items, a) + } + } + return items + +} + +// GetAppProjectByName returns a project from an application based on name +func GetAppProjectByName(name string, projLister applicationsv1.AppProjectLister, ns string, settingsManager *settings.SettingsManager, db db.ArgoDB, ctx context.Context) (*argoappv1.AppProject, error) { + projOrig, err := projLister.AppProjects(ns).Get(name) + if err != nil { + return nil, err + } + project := projOrig.DeepCopy() + repos := retrieveScopedRepositories(name, db, ctx) + for _, repo := range repos { + project.Spec.SourceRepos = append(project.Spec.SourceRepos, repo.Repo) + } + clusters := retrieveScopedClusters(name, db, ctx) + for _, cluster := range clusters { + if len(cluster.Namespaces) == 0 { + project.Spec.Destinations = append(project.Spec.Destinations, argoappv1.ApplicationDestination{Server: cluster.Server, Namespace: "*"}) + } else { + for _, ns := range cluster.Namespaces { + project.Spec.Destinations = append(project.Spec.Destinations, argoappv1.ApplicationDestination{Server: cluster.Server, Namespace: ns}) + } + } + } + return GetAppVirtualProject(project, projLister, settingsManager) +} + +func GetAppVirtualProject(proj *argoappv1.AppProject, projLister applicationsv1.AppProjectLister, settingsManager *settings.SettingsManager) (*argoappv1.AppProject, error) { + virtualProj := proj.DeepCopy() + globalProjects := GetGlobalProjects(proj, projLister, settingsManager) + + for _, gp := range globalProjects { + virtualProj = mergeVirtualProject(virtualProj, gp) + } + return virtualProj, nil +} + +// GetAppProject returns a project from an application +func GetAppProject(spec *argoappv1.ApplicationSpec, projLister applicationsv1.AppProjectLister, ns string, settingsManager *settings.SettingsManager, db db.ArgoDB, ctx context.Context) (*argoappv1.AppProject, error) { + return GetAppProjectByName(spec.GetProject(), projLister, ns, settingsManager, db, ctx) +} + +func GetGlobalProjects(proj *argoappv1.AppProject, projLister applicationsv1.AppProjectLister, settingsManager *settings.SettingsManager) []*argoappv1.AppProject { + gps, err := settingsManager.GetGlobalProjectsSettings() + globalProjects := make([]*argoappv1.AppProject, 0) + + if err != nil { + log.Warnf("Failed to get global project settings: %v", err) + return globalProjects + } + + for _, gp := range gps { + //The project itself is not its own the global project + if proj.Name == gp.ProjectName { + continue + } + + selector, err := metav1.LabelSelectorAsSelector(&gp.LabelSelector) + if err != nil { + break + } + //Get projects which match the label selector, then see if proj is a match + projList, err := projLister.AppProjects(proj.Namespace).List(selector) + if err != nil { + break + } + var matchMe bool + for _, item := range projList { + if item.Name == proj.Name { + matchMe = true + break + } + } + if !matchMe { + continue + } + //If proj is a match for this global project setting, then it is its global project + globalProj, err := projLister.AppProjects(proj.Namespace).Get(gp.ProjectName) + if err != nil { + break + } + globalProjects = append(globalProjects, globalProj) + + } + return globalProjects +} + +func mergeVirtualProject(proj *argoappv1.AppProject, globalProj *argoappv1.AppProject) *argoappv1.AppProject { + if globalProj == nil { + return proj + } + proj.Spec.ClusterResourceWhitelist = append(proj.Spec.ClusterResourceWhitelist, globalProj.Spec.ClusterResourceWhitelist...) + proj.Spec.ClusterResourceBlacklist = append(proj.Spec.ClusterResourceBlacklist, globalProj.Spec.ClusterResourceBlacklist...) + + proj.Spec.NamespaceResourceWhitelist = append(proj.Spec.NamespaceResourceWhitelist, globalProj.Spec.NamespaceResourceWhitelist...) + proj.Spec.NamespaceResourceBlacklist = append(proj.Spec.NamespaceResourceBlacklist, globalProj.Spec.NamespaceResourceBlacklist...) + + proj.Spec.SyncWindows = append(proj.Spec.SyncWindows, globalProj.Spec.SyncWindows...) + + proj.Spec.SourceRepos = append(proj.Spec.SourceRepos, globalProj.Spec.SourceRepos...) + + proj.Spec.Destinations = append(proj.Spec.Destinations, globalProj.Spec.Destinations...) + + return proj +}