Compare commits

...

34 Commits

Author SHA1 Message Date
github-actions[bot]
102853d31a Bump version to 2.13.4 on release-2.13 branch (#21709)
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: ishitasequeira <46771830+ishitasequeira@users.noreply.github.com>
2025-01-29 15:15:49 -05:00
Siddhesh Ghadi
10b9589f1c Merge commit from fork
Signed-off-by: Siddhesh Ghadi <sghadi1203@gmail.com>
2025-01-29 13:41:18 -05:00
Esteban Molina-Estolano
53dc116353 fix: oras-go client should fallback to docker config if no credentials specified (cherry-pick 2.13 #18133) (#20872)
Signed-off-by: Tony Au-Yeung <tony@elevenlabs.io>
Co-authored-by: Tony Au-Yeung <tonyay163@gmail.com>
2025-01-22 10:48:00 -05:00
gcp-cherry-pick-bot[bot]
99aaf43bdb fix: Policy/policy.open-cluster-management.io stuck in progressing status when no clusters match the policy (#21296) (cherry-pick #21297) (#21594)
Signed-off-by: Michele Baldessari <michele@acksyn.org>
Co-authored-by: Michele Baldessari <michele@acksyn.org>
2025-01-21 13:44:55 -05:00
gcp-cherry-pick-bot[bot]
c8a62bb162 docs: add mkdocs configuration stanza to .readthedocs.yaml (cherry-pick #21475) (#21609)
Signed-off-by: reggie-k <regina.voloshin@codefresh.io>
Co-authored-by: Regina Voloshin <regina.voloshin@codefresh.io>
2025-01-21 13:14:06 -05:00
gcp-cherry-pick-bot[bot]
fd67e4970f fix: resolve the failing e2e appset tests for ksonnet applications (cherry-pick #21580) (#21605)
Signed-off-by: reggie-k <regina.voloshin@codefresh.io>
Co-authored-by: Regina Voloshin <regina.voloshin@codefresh.io>
2025-01-21 13:13:17 -05:00
gcp-cherry-pick-bot[bot]
2618ccca2d fix: login return_url doesn't work with custom server paths (cherry-pick #21588) (#21603)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
Co-authored-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2025-01-21 09:25:39 -08:00
Atif Ali
38e02ab9e8 chore(deps): bump go-git version to go-git/v5 5.13.1 (#21551)
Signed-off-by: Atif Ali <atali@redhat.com>
2025-01-20 20:08:16 -05:00
Eadred
2fe4536ed2 fix(appset): events not honouring configured namespaces (#21219) (#21241) (#21520)
* fix: 21219 Honour ARGOCD_APPLICATIONSET_CONTROLLER_NAMESPACES for all ApplicationSet events

Namespace filtering is applied to Update, Delete and Generic events.

Fixes https://github.com/argoproj/argo-cd/issues/21219



* fix: 21219 Add tests for ignoreNotAllowedNamespaces



* fix: 21219 Remove redundant package import



---------

Signed-off-by: eadred <eadred77@googlemail.com>
2025-01-17 10:58:14 -05:00
gcp-cherry-pick-bot[bot]
49163b09b1 Fix application url for custom base href (#21377) (#21515)
Signed-off-by: Amit Oren <amit@coralogix.com>
Co-authored-by: Amit Oren <amit@coralogix.com>
2025-01-16 00:46:32 -05:00
gcp-cherry-pick-bot[bot]
c0f847f301 docs: Update Screenshot in Orphaned Resources Monitoring Section #20510 (cherry-pick #20533) (#21489)
Signed-off-by: jaehanbyun <awbrg789@naver.com>
2025-01-14 11:30:01 -05:00
gcp-cherry-pick-bot[bot]
2e794fbbc5 chore(deps): bump github.com/go-git/go-git/v5 from 5.12.0 to 5.13.0 (cherry-pick #21329) (#21401)
* chore(deps): bump github.com/go-git/go-git/v5 from 5.12.0 to 5.13.0 (#21329)

Bumps [github.com/go-git/go-git/v5](https://github.com/go-git/go-git) from 5.12.0 to 5.13.0.
- [Release notes](https://github.com/go-git/go-git/releases)
- [Commits](https://github.com/go-git/go-git/compare/v5.12.0...v5.13.0)

---
updated-dependencies:
- dependency-name: github.com/go-git/go-git/v5
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* tidy

Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>

---------

Signed-off-by: dependabot[bot] <support@github.com>
Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
2025-01-13 09:51:16 -05:00
github-actions[bot]
a25c8a0eef Bump version to 2.13.3 (#21359)
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: crenshaw-dev <350466+crenshaw-dev@users.noreply.github.com>
2025-01-03 13:39:40 -05:00
gcp-cherry-pick-bot[bot]
c76a131b17 fix: Change applicationset generate HTTP method to avoid route conflicts (#20758) (#21300)
* Change applicationset generate HTTP method to avoid route conflicts



* Update server/applicationset/applicationset.proto




* Codegen



---------

Signed-off-by: Amit Oren <amit@coralogix.com>
Signed-off-by: Amit Oren <github@amitoren.dev>
Co-authored-by: Amit Oren <amit@coralogix.com>
Co-authored-by: Alexandre Gaudreault <alexandre_gaudreault@intuit.com>
2024-12-30 11:54:06 +02:00
Michael Crenshaw
64a14a08e0 fix(ui): add optional check to avoid undefined reference in project detail (#20044) (#21263)
Signed-off-by: linghaoSu <linghao.su@daocloud.io>
Co-authored-by: Linghao Su <linghao.su@daocloud.io>
2024-12-19 15:37:36 -05:00
gcp-cherry-pick-bot[bot]
09eede0c17 fix(appset): Fix appset generate in --core mode for cluster gen (#21170) (#21236)
Signed-off-by: OpenGuidou <guillaume.doussin@gmail.com>
Co-authored-by: OpenGuidou <73480729+OpenGuidou@users.noreply.github.com>
2024-12-18 14:48:12 +05:30
gcp-cherry-pick-bot[bot]
f260510f38 fix(api): send to closed channel in mergeLogStreams (#7006) (#21178) (#21187)
* fix(api): send to closed channel in mergeLogStreams (#7006)



* more intense test



* even more intense



* remove unnecessary comment



* fix the race condition



---------

Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
Co-authored-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
2024-12-15 20:58:05 -05:00
adriananeci
079754c639 fix: Populate destination name when destination server is specified (#21063) (cherry-pick 2.13) (#21176)
* fix: Populate destination name when destination server is specified (#21063)

* Populate destination name when destination server is specified

Signed-off-by: Adrian Aneci <aneci@adobe.com>

---------

Signed-off-by: Adrian Aneci <aneci@adobe.com>

* Go lint fixes

Signed-off-by: Adrian Aneci <aneci@adobe.com>

---------

Signed-off-by: Adrian Aneci <aneci@adobe.com>
2024-12-14 14:18:36 +05:30
github-actions[bot]
dc43124058 Bump version to 2.13.2 (#21133)
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: ishitasequeira <46771830+ishitasequeira@users.noreply.github.com>
2024-12-11 20:26:41 +05:30
Blake Pettersson
b6af657295 fix: add missing fields in listrepositories (#20991) (#21129)
This fixes a regression in 2.12. Before 2.12 githubAppInstallationID,
`githubAppID` and `gitHubAppEnterpriseBaseURL` were returned, but with
2.12 the repo is retrieved with getRepositories`, which does not
include those fields.

To fix this, add those missing fields to `ListRepositories`.

Signed-off-by: Blake Pettersson <blake.pettersson@gmail.com>
2024-12-11 12:17:21 +01:00
gcp-cherry-pick-bot[bot]
a3624a3f20 fix: Allow to delete repos with invalid urls (#20921) (#20975) (#21116)
* fix: Allow to delete repos with invalid urls (#20921)

Fixes #20921

Normalization of repo url is attempted during repo deletion before comparison with existing repos. Before this change, it'd fail on invalid urls and return "", resulting in permission denied. This ended up in a state where people can add repos with invalid urls but couldn't delete them. Return raw repo url if url parsing failed. Add a test to validate the deletion can be performed and make sure it fails without the main change.

This needs to be cherry-picked to v2.11-2.13



* Don't modify the original NormalizeGitURL



---------

Signed-off-by: Andrii Korotkov <andrii.korotkov@verkada.com>
Co-authored-by: Andrii Korotkov <137232734+andrii-korotkov-verkada@users.noreply.github.com>
2024-12-10 16:28:27 +02:00
gcp-cherry-pick-bot[bot]
01ae20d1b3 fix: 20791 - sync multi-source application out of order source syncs (cherry-pick #21071) (#21077)
Signed-off-by: Ishita Sequeira <ishiseq29@gmail.com>
Co-authored-by: Ishita Sequeira <46771830+ishitasequeira@users.noreply.github.com>
2024-12-05 11:14:25 -07:00
gcp-cherry-pick-bot[bot]
89ef3563db fix: Bitbucket Cloud PR Author is processed correctly (#20769) (#20990) (#21039)
Fixes #20769

Author there is a struct, not a string. Use nickname from that struct as an author name.

Let's cherry pick to 2.11-2.13

Signed-off-by: Andrii Korotkov <andrii.korotkov@verkada.com>
Co-authored-by: Andrii Korotkov <137232734+andrii-korotkov-verkada@users.noreply.github.com>
2024-12-03 17:02:24 +05:30
gcp-cherry-pick-bot[bot]
831e4525c3 fix: API server should not attempt to read secrets in all namespaces (#20950) (#20960)
* fix: api server is trying to list cluster wide secrets while generating apps



* Revert "fix: Fix argocd appset generate failure due to missing clusterrole (#20162)"

This reverts commit fad534bcfe.

---------

Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
Co-authored-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2024-11-26 19:43:12 +05:30
gcp-cherry-pick-bot[bot]
f8d6665c67 fix: Memory leak in repo-server (#20876) (#20894)
Signed-off-by: Adam Chandler <adam_chandler@trimble.com>
Co-authored-by: Adam Chandler <31355738+AJChandler@users.noreply.github.com>
2024-11-21 10:08:04 -05:00
gcp-cherry-pick-bot[bot]
0680ddbdf9 chore(deps): bump http-proxy-middleware from 2.0.4 to 2.0.7 in /ui (#20518) (#20892)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-11-21 08:44:53 -05:00
gcp-cherry-pick-bot[bot]
ad36916ec4 fix(cli): Fix appset generate in --core mode (#20717) (#20883)
Signed-off-by: OpenGuidou <guillaume.doussin@gmail.com>
Co-authored-by: OpenGuidou <73480729+OpenGuidou@users.noreply.github.com>
2024-11-21 17:36:31 +05:30
github-actions[bot]
af54ef8db5 Bump version to 2.13.1 (#20865)
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: pasha-codefresh <39732895+pasha-codefresh@users.noreply.github.com>
2024-11-20 17:45:30 +02:00
gcp-cherry-pick-bot[bot]
68606c6caf fix: Fix repeated 403 due to app namespace being undefined (#20699) (#20819) (#20860)
Fixes #20699

Constructor may not get called every time the application changes, so previous this.appNamespace could be stale. But the update to use `this.props.match.params.appnamespace` could also fail if it's undefined.
As a fix, create and use a helper function `getAppNamespace` which has a special case handling for undefined.

Also, use a namespaced endpoint when namespace is not undefined.

It needs to be cherry-picked to v2.11-2.13.

Signed-off-by: Andrii Korotkov <andrii.korotkov@verkada.com>
Co-authored-by: Andrii Korotkov <137232734+andrii-korotkov-verkada@users.noreply.github.com>
2024-11-20 13:13:11 +02:00
Cayde6
6a8cb6eff0 feat: option to disable writing k8s events(#18205) (#18441) (#20788)
* feat: option to disable writing k8s events

optioned to write logs for k8s events.
Each is passed as an environment variable and defaults to true,
disabling it requires explicitly setting the option to false.

---------

Signed-off-by: Jack-R-lantern <tjdfkr2421@gmail.com>
2024-11-14 13:07:04 +05:30
Pasha Kostohrys
d03ccf305c fix: disable automaxprocs logging (#20069) - cherry-pick 2.13 (#20718)
* fix: disable automaxprocs logging (#20069)

* disable automaxprocs logging

Signed-off-by: nitishfy <justnitish06@gmail.com>

fix lint checks

Signed-off-by: nitishfy <justnitish06@gmail.com>

move maxprocs to main.go

Signed-off-by: nitishfy <justnitish06@gmail.com>

move set auto max procs to a function

Signed-off-by: nitishfy <justnitish06@gmail.com>

add info log

Signed-off-by: nitishfy <justnitish06@gmail.com>

* add info log

Signed-off-by: nitishfy <justnitish06@gmail.com>

* fix lint checks

Signed-off-by: nitishfy <justnitish06@gmail.com>

* fix lint checks

Signed-off-by: nitishfy <justnitish06@gmail.com>

* add unit test

Signed-off-by: nitishfy <justnitish06@gmail.com>

* fix lint issues

Signed-off-by: nitishfy <justnitish06@gmail.com>

---------

Signed-off-by: nitishfy <justnitish06@gmail.com>
(cherry picked from commit cfa1c89c43)

* fix(ci): ignore temporary files when checking for out of bound symlinks (#20527)

Signed-off-by: cef <moncef.abboud95@gmail.com>

---------

Signed-off-by: cef <moncef.abboud95@gmail.com>
Co-authored-by: Nitish Kumar <justnitish06@gmail.com>
Co-authored-by: ABBOUD Moncef <moncef.abboud95@gmail.com>
2024-11-08 19:46:49 +02:00
gcp-cherry-pick-bot[bot]
7f45c9e093 chore: Don't degrade PDB on InsufficientPods (#20171) (#20665) (#20694)
Closes #20171

There are valid use cases for InsufficientPods, e.g. running some jobs or tests that don't want to be terminated. See the discussion on the issue for more details. So don't degrade the PDB on InsufficientPods condition.

This needs to be cherry picked to 2.13, as many people may not upgrade otherwise.

Signed-off-by: Andrii Korotkov <andrii.korotkov@verkada.com>
Co-authored-by: Andrii Korotkov <137232734+andrii-korotkov-verkada@users.noreply.github.com>
2024-11-07 09:11:01 -08:00
austin5219
449e6939b2 fix(pkce): 20202 Backport PKCE auth flow fix for basehref and reauth (#20675)
* fix(pkce): 20111 PKCE auth flow does not return user to previous path like dex auth flow (#20202)

* Adding non-default basehref support for PKCE auth flow

Signed-off-by: austin5219 <3936059+austin5219@users.noreply.github.com>

* Adding ; for linting

Signed-off-by: austin5219 <3936059+austin5219@users.noreply.github.com>

* removing hook function

Signed-off-by: austin5219 <3936059+austin5219@users.noreply.github.com>

* Moving unauthorized error handling to class component to access context for error handling within 401 error

Signed-off-by: austin5219 <3936059+austin5219@users.noreply.github.com>

* Store the subsrition handle to close in unmount

Signed-off-by: austin5219 <3936059+austin5219@users.noreply.github.com>

* reorder imports

Signed-off-by: austin5219 <3936059+austin5219@users.noreply.github.com>

* Actually saving the subscriptions now

Signed-off-by: austin5219 <3936059+austin5219@users.noreply.github.com>

* returning the 401 subscription from helper function

Signed-off-by: austin5219 <3936059+austin5219@users.noreply.github.com>

* Handle the promise of a subscription

Signed-off-by: austin5219 <3936059+austin5219@users.noreply.github.com>

* Removing then from non async subscribe

Signed-off-by: austin5219 <3936059+austin5219@users.noreply.github.com>

* Linter fixes

Signed-off-by: austin5219 <3936059+austin5219@users.noreply.github.com>

* Adding path caching to sessionStorage on pkceLogin and redirect step to cached path if available in pkceCallback to mirror Dex functionality

Signed-off-by: austin5219 <3936059+austin5219@users.noreply.github.com>

---------

Signed-off-by: austin5219 <3936059+austin5219@users.noreply.github.com>

* Merge Conflict fix

Signed-off-by: austin5219 <3936059+austin5219@users.noreply.github.com>

---------

Signed-off-by: austin5219 <3936059+austin5219@users.noreply.github.com>
2024-11-07 15:47:09 +02:00
gcp-cherry-pick-bot[bot]
99aab9a5f3 fix: check for source position when --show-params is set (#20682) (#20689)
Signed-off-by: Soumya Ghosh Dastidar <gdsoumya@gmail.com>
Co-authored-by: Soumya Ghosh Dastidar <44349253+gdsoumya@users.noreply.github.com>
2024-11-07 12:51:49 +05:30
83 changed files with 1259 additions and 469 deletions

View File

@@ -2,6 +2,7 @@ version: 2
formats: all
mkdocs:
fail_on_warning: false
configuration: mkdocs.yml
python:
install:
- requirements: docs/requirements.txt

View File

@@ -1 +1 @@
2.13.0
2.13.4

View File

@@ -510,11 +510,9 @@ func (r *ApplicationSetReconciler) getMinRequeueAfter(applicationSetInfo *argov1
}
func ignoreNotAllowedNamespaces(namespaces []string) predicate.Predicate {
return predicate.Funcs{
CreateFunc: func(e event.CreateEvent) bool {
return utils.IsNamespaceAllowed(namespaces, e.Object.GetNamespace())
},
}
return predicate.NewPredicateFuncs(func(object client.Object) bool {
return utils.IsNamespaceAllowed(namespaces, object.GetNamespace())
})
}
func appControllerIndexer(rawObj client.Object) []string {

View File

@@ -36,6 +36,7 @@ import (
"github.com/argoproj/argo-cd/v2/applicationset/utils"
appsetmetrics "github.com/argoproj/argo-cd/v2/applicationset/metrics"
argocommon "github.com/argoproj/argo-cd/v2/common"
"github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1"
appclientset "github.com/argoproj/argo-cd/v2/pkg/client/clientset/versioned/fake"
dbmocks "github.com/argoproj/argo-cd/v2/util/db/mocks"
@@ -48,9 +49,6 @@ func TestCreateOrUpdateInCluster(t *testing.T) {
err := v1alpha1.AddToScheme(scheme)
require.NoError(t, err)
err = v1alpha1.AddToScheme(scheme)
require.NoError(t, err)
for _, c := range []struct {
// name is human-readable test name
name string
@@ -1091,9 +1089,6 @@ func TestRemoveFinalizerOnInvalidDestination_FinalizerTypes(t *testing.T) {
err := v1alpha1.AddToScheme(scheme)
require.NoError(t, err)
err = v1alpha1.AddToScheme(scheme)
require.NoError(t, err)
for _, c := range []struct {
// name is human-readable test name
name string
@@ -1214,9 +1209,6 @@ func TestRemoveFinalizerOnInvalidDestination_DestinationTypes(t *testing.T) {
err := v1alpha1.AddToScheme(scheme)
require.NoError(t, err)
err = v1alpha1.AddToScheme(scheme)
require.NoError(t, err)
for _, c := range []struct {
// name is human-readable test name
name string
@@ -1371,9 +1363,6 @@ func TestRemoveOwnerReferencesOnDeleteAppSet(t *testing.T) {
err := v1alpha1.AddToScheme(scheme)
require.NoError(t, err)
err = v1alpha1.AddToScheme(scheme)
require.NoError(t, err)
for _, c := range []struct {
// name is human-readable test name
name string
@@ -1447,9 +1436,6 @@ func TestCreateApplications(t *testing.T) {
err := v1alpha1.AddToScheme(scheme)
require.NoError(t, err)
err = v1alpha1.AddToScheme(scheme)
require.NoError(t, err)
testCases := []struct {
name string
appSet v1alpha1.ApplicationSet
@@ -1653,8 +1639,6 @@ func TestDeleteInCluster(t *testing.T) {
scheme := runtime.NewScheme()
err := v1alpha1.AddToScheme(scheme)
require.NoError(t, err)
err = v1alpha1.AddToScheme(scheme)
require.NoError(t, err)
for _, c := range []struct {
// appSet is the application set on which the delete function is called
@@ -1809,8 +1793,6 @@ func TestGetMinRequeueAfter(t *testing.T) {
scheme := runtime.NewScheme()
err := v1alpha1.AddToScheme(scheme)
require.NoError(t, err)
err = v1alpha1.AddToScheme(scheme)
require.NoError(t, err)
client := fake.NewClientBuilder().WithScheme(scheme).Build()
metrics := appsetmetrics.NewFakeAppsetMetrics(client)
@@ -1858,8 +1840,6 @@ func TestRequeueGeneratorFails(t *testing.T) {
scheme := runtime.NewScheme()
err := v1alpha1.AddToScheme(scheme)
require.NoError(t, err)
err = v1alpha1.AddToScheme(scheme)
require.NoError(t, err)
appSet := v1alpha1.ApplicationSet{
ObjectMeta: metav1.ObjectMeta{
@@ -1913,18 +1893,6 @@ func TestValidateGeneratedApplications(t *testing.T) {
err := v1alpha1.AddToScheme(scheme)
require.NoError(t, err)
err = v1alpha1.AddToScheme(scheme)
require.NoError(t, err)
client := fake.NewClientBuilder().WithScheme(scheme).Build()
metrics := appsetmetrics.NewFakeAppsetMetrics(client)
// Valid cluster
myCluster := v1alpha1.Cluster{
Server: "https://kubernetes.default.svc",
Name: "my-cluster",
}
// Valid project
myProject := &v1alpha1.AppProject{
ObjectMeta: metav1.ObjectMeta{Name: "default", Namespace: "namespace"},
@@ -1945,6 +1913,9 @@ func TestValidateGeneratedApplications(t *testing.T) {
},
}
client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(myProject).Build()
metrics := appsetmetrics.NewFakeAppsetMetrics(client)
// Test a subset of the validations that 'validateGeneratedApplications' performs
for _, cc := range []struct {
name string
@@ -2088,12 +2059,6 @@ func TestValidateGeneratedApplications(t *testing.T) {
objects := append([]runtime.Object{}, secret)
kubeclientset := kubefake.NewSimpleClientset(objects...)
argoDBMock := dbmocks.ArgoDB{}
argoDBMock.On("GetCluster", mock.Anything, "https://kubernetes.default.svc").Return(&myCluster, nil)
argoDBMock.On("ListClusters", mock.Anything).Return(&v1alpha1.ClusterList{Items: []v1alpha1.Cluster{
myCluster,
}}, nil)
argoObjs := []runtime.Object{myProject}
for _, app := range cc.apps {
argoObjs = append(argoObjs, &app)
@@ -2104,7 +2069,7 @@ func TestValidateGeneratedApplications(t *testing.T) {
Scheme: scheme,
Recorder: record.NewFakeRecorder(1),
Generators: map[string]generators.Generator{},
ArgoDB: &argoDBMock,
ArgoDB: &dbmocks.ArgoDB{},
ArgoCDNamespace: "namespace",
ArgoAppClientset: appclientset.NewSimpleClientset(argoObjs...),
KubeClientset: kubeclientset,
@@ -2150,8 +2115,6 @@ func TestReconcilerValidationProjectErrorBehaviour(t *testing.T) {
scheme := runtime.NewScheme()
err := v1alpha1.AddToScheme(scheme)
require.NoError(t, err)
err = v1alpha1.AddToScheme(scheme)
require.NoError(t, err)
project := v1alpha1.AppProject{
ObjectMeta: metav1.ObjectMeta{Name: "good-project", Namespace: "argocd"},
@@ -2189,18 +2152,10 @@ func TestReconcilerValidationProjectErrorBehaviour(t *testing.T) {
}
kubeclientset := kubefake.NewSimpleClientset()
argoDBMock := dbmocks.ArgoDB{}
argoObjs := []runtime.Object{&project}
client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(&appSet).WithStatusSubresource(&appSet).WithIndex(&v1alpha1.Application{}, ".metadata.controller", appControllerIndexer).Build()
metrics := appsetmetrics.NewFakeAppsetMetrics(client)
goodCluster := v1alpha1.Cluster{Server: "https://good-cluster", Name: "good-cluster"}
badCluster := v1alpha1.Cluster{Server: "https://bad-cluster", Name: "bad-cluster"}
argoDBMock.On("GetCluster", mock.Anything, "https://good-cluster").Return(&goodCluster, nil)
argoDBMock.On("GetCluster", mock.Anything, "https://bad-cluster").Return(&badCluster, nil)
argoDBMock.On("ListClusters", mock.Anything).Return(&v1alpha1.ClusterList{Items: []v1alpha1.Cluster{
goodCluster,
}}, nil)
r := ApplicationSetReconciler{
Client: client,
@@ -2210,7 +2165,7 @@ func TestReconcilerValidationProjectErrorBehaviour(t *testing.T) {
Generators: map[string]generators.Generator{
"List": generators.NewListGenerator(),
},
ArgoDB: &argoDBMock,
ArgoDB: &dbmocks.ArgoDB{},
ArgoAppClientset: appclientset.NewSimpleClientset(argoObjs...),
KubeClientset: kubeclientset,
Policy: v1alpha1.ApplicationsSyncPolicySync,
@@ -2246,8 +2201,6 @@ func TestSetApplicationSetStatusCondition(t *testing.T) {
scheme := runtime.NewScheme()
err := v1alpha1.AddToScheme(scheme)
require.NoError(t, err)
err = v1alpha1.AddToScheme(scheme)
require.NoError(t, err)
testCases := []struct {
appset v1alpha1.ApplicationSet
@@ -2394,7 +2347,6 @@ func TestSetApplicationSetStatusCondition(t *testing.T) {
}
kubeclientset := kubefake.NewSimpleClientset([]runtime.Object{}...)
argoDBMock := dbmocks.ArgoDB{}
argoObjs := []runtime.Object{}
for _, testCase := range testCases {
@@ -2409,7 +2361,7 @@ func TestSetApplicationSetStatusCondition(t *testing.T) {
Generators: map[string]generators.Generator{
"List": generators.NewListGenerator(),
},
ArgoDB: &argoDBMock,
ArgoDB: &dbmocks.ArgoDB{},
ArgoAppClientset: appclientset.NewSimpleClientset(argoObjs...),
KubeClientset: kubeclientset,
Metrics: metrics,
@@ -2428,8 +2380,6 @@ func applicationsUpdateSyncPolicyTest(t *testing.T, applicationsSyncPolicy v1alp
scheme := runtime.NewScheme()
err := v1alpha1.AddToScheme(scheme)
require.NoError(t, err)
err = v1alpha1.AddToScheme(scheme)
require.NoError(t, err)
defaultProject := v1alpha1.AppProject{
ObjectMeta: metav1.ObjectMeta{Name: "default", Namespace: "argocd"},
@@ -2467,17 +2417,30 @@ func applicationsUpdateSyncPolicyTest(t *testing.T, applicationsSyncPolicy v1alp
},
}
kubeclientset := kubefake.NewSimpleClientset()
argoDBMock := dbmocks.ArgoDB{}
argoObjs := []runtime.Object{&defaultProject}
secret := &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: "my-cluster",
Namespace: "argocd",
Labels: map[string]string{
argocommon.LabelKeySecretType: argocommon.LabelValueSecretTypeCluster,
},
},
Data: map[string][]byte{
// Since this test requires the cluster to be an invalid destination, we
// always return a cluster named 'my-cluster2' (different from app 'my-cluster', above)
"name": []byte("good-cluster"),
"server": []byte("https://good-cluster"),
"config": []byte("{\"username\":\"foo\",\"password\":\"foo\"}"),
},
}
objects := append([]runtime.Object{}, secret)
kubeclientset := kubefake.NewSimpleClientset(objects...)
client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(&appSet).WithStatusSubresource(&appSet).WithIndex(&v1alpha1.Application{}, ".metadata.controller", appControllerIndexer).Build()
metrics := appsetmetrics.NewFakeAppsetMetrics(client)
goodCluster := v1alpha1.Cluster{Server: "https://good-cluster", Name: "good-cluster"}
argoDBMock.On("GetCluster", mock.Anything, "https://good-cluster").Return(&goodCluster, nil)
argoDBMock.On("ListClusters", mock.Anything).Return(&v1alpha1.ClusterList{Items: []v1alpha1.Cluster{
goodCluster,
}}, nil)
r := ApplicationSetReconciler{
Client: client,
@@ -2487,7 +2450,7 @@ func applicationsUpdateSyncPolicyTest(t *testing.T, applicationsSyncPolicy v1alp
Generators: map[string]generators.Generator{
"List": generators.NewListGenerator(),
},
ArgoDB: &argoDBMock,
ArgoDB: &dbmocks.ArgoDB{},
ArgoCDNamespace: "argocd",
ArgoAppClientset: appclientset.NewSimpleClientset(argoObjs...),
KubeClientset: kubeclientset,
@@ -2593,8 +2556,6 @@ func applicationsDeleteSyncPolicyTest(t *testing.T, applicationsSyncPolicy v1alp
scheme := runtime.NewScheme()
err := v1alpha1.AddToScheme(scheme)
require.NoError(t, err)
err = v1alpha1.AddToScheme(scheme)
require.NoError(t, err)
defaultProject := v1alpha1.AppProject{
ObjectMeta: metav1.ObjectMeta{Name: "default", Namespace: "argocd"},
@@ -2632,17 +2593,30 @@ func applicationsDeleteSyncPolicyTest(t *testing.T, applicationsSyncPolicy v1alp
},
}
kubeclientset := kubefake.NewSimpleClientset()
argoDBMock := dbmocks.ArgoDB{}
argoObjs := []runtime.Object{&defaultProject}
secret := &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: "my-cluster",
Namespace: "argocd",
Labels: map[string]string{
argocommon.LabelKeySecretType: argocommon.LabelValueSecretTypeCluster,
},
},
Data: map[string][]byte{
// Since this test requires the cluster to be an invalid destination, we
// always return a cluster named 'my-cluster2' (different from app 'my-cluster', above)
"name": []byte("good-cluster"),
"server": []byte("https://good-cluster"),
"config": []byte("{\"username\":\"foo\",\"password\":\"foo\"}"),
},
}
objects := append([]runtime.Object{}, secret)
kubeclientset := kubefake.NewSimpleClientset(objects...)
client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(&appSet).WithStatusSubresource(&appSet).WithIndex(&v1alpha1.Application{}, ".metadata.controller", appControllerIndexer).Build()
metrics := appsetmetrics.NewFakeAppsetMetrics(client)
goodCluster := v1alpha1.Cluster{Server: "https://good-cluster", Name: "good-cluster"}
argoDBMock.On("GetCluster", mock.Anything, "https://good-cluster").Return(&goodCluster, nil)
argoDBMock.On("ListClusters", mock.Anything).Return(&v1alpha1.ClusterList{Items: []v1alpha1.Cluster{
goodCluster,
}}, nil)
r := ApplicationSetReconciler{
Client: client,
@@ -2652,7 +2626,7 @@ func applicationsDeleteSyncPolicyTest(t *testing.T, applicationsSyncPolicy v1alp
Generators: map[string]generators.Generator{
"List": generators.NewListGenerator(),
},
ArgoDB: &argoDBMock,
ArgoDB: &dbmocks.ArgoDB{},
ArgoCDNamespace: "argocd",
ArgoAppClientset: appclientset.NewSimpleClientset(argoObjs...),
KubeClientset: kubeclientset,
@@ -2728,7 +2702,7 @@ func TestDeletePerformedWithSyncPolicyCreateDelete(t *testing.T) {
apps := applicationsDeleteSyncPolicyTest(t, applicationsSyncPolicy, 3, true)
assert.Empty(t, apps.Items)
assert.NotNil(t, apps.Items[0].DeletionTimestamp)
}
func TestDeletePerformedWithSyncPolicySync(t *testing.T) {
@@ -2736,7 +2710,7 @@ func TestDeletePerformedWithSyncPolicySync(t *testing.T) {
apps := applicationsDeleteSyncPolicyTest(t, applicationsSyncPolicy, 3, true)
assert.Empty(t, apps.Items)
assert.NotNil(t, apps.Items[0].DeletionTimestamp)
}
func TestDeletePerformedWithSyncPolicyCreateOnlyAndAllowPolicyOverrideFalse(t *testing.T) {
@@ -2744,7 +2718,7 @@ func TestDeletePerformedWithSyncPolicyCreateOnlyAndAllowPolicyOverrideFalse(t *t
apps := applicationsDeleteSyncPolicyTest(t, applicationsSyncPolicy, 3, false)
assert.Empty(t, apps.Items)
assert.NotNil(t, apps.Items[0].DeletionTimestamp)
}
func TestPolicies(t *testing.T) {
@@ -2752,21 +2726,12 @@ func TestPolicies(t *testing.T) {
err := v1alpha1.AddToScheme(scheme)
require.NoError(t, err)
err = v1alpha1.AddToScheme(scheme)
require.NoError(t, err)
defaultProject := v1alpha1.AppProject{
ObjectMeta: metav1.ObjectMeta{Name: "default", Namespace: "argocd"},
Spec: v1alpha1.AppProjectSpec{SourceRepos: []string{"*"}, Destinations: []v1alpha1.ApplicationDestination{{Namespace: "*", Server: "https://kubernetes.default.svc"}}},
}
myCluster := v1alpha1.Cluster{
Server: "https://kubernetes.default.svc",
Name: "my-cluster",
}
kubeclientset := kubefake.NewSimpleClientset()
argoDBMock := dbmocks.ArgoDB{}
argoDBMock.On("GetCluster", mock.Anything, "https://kubernetes.default.svc").Return(&myCluster, nil)
argoObjs := []runtime.Object{&defaultProject}
for _, c := range []struct {
@@ -2850,7 +2815,7 @@ func TestPolicies(t *testing.T) {
Generators: map[string]generators.Generator{
"List": generators.NewListGenerator(),
},
ArgoDB: &argoDBMock,
ArgoDB: &dbmocks.ArgoDB{},
ArgoCDNamespace: "argocd",
ArgoAppClientset: appclientset.NewSimpleClientset(argoObjs...),
KubeClientset: kubeclientset,
@@ -2923,11 +2888,8 @@ func TestSetApplicationSetApplicationStatus(t *testing.T) {
scheme := runtime.NewScheme()
err := v1alpha1.AddToScheme(scheme)
require.NoError(t, err)
err = v1alpha1.AddToScheme(scheme)
require.NoError(t, err)
kubeclientset := kubefake.NewSimpleClientset([]runtime.Object{}...)
argoDBMock := dbmocks.ArgoDB{}
argoObjs := []runtime.Object{}
for _, cc := range []struct {
@@ -3012,7 +2974,7 @@ func TestSetApplicationSetApplicationStatus(t *testing.T) {
Generators: map[string]generators.Generator{
"List": generators.NewListGenerator(),
},
ArgoDB: &argoDBMock,
ArgoDB: &dbmocks.ArgoDB{},
ArgoAppClientset: appclientset.NewSimpleClientset(argoObjs...),
KubeClientset: kubeclientset,
Metrics: metrics,
@@ -3031,9 +2993,6 @@ func TestBuildAppDependencyList(t *testing.T) {
err := v1alpha1.AddToScheme(scheme)
require.NoError(t, err)
err = v1alpha1.AddToScheme(scheme)
require.NoError(t, err)
client := fake.NewClientBuilder().WithScheme(scheme).Build()
metrics := appsetmetrics.NewFakeAppsetMetrics(client)
@@ -3765,7 +3724,6 @@ func TestBuildAppDependencyList(t *testing.T) {
} {
t.Run(cc.name, func(t *testing.T) {
kubeclientset := kubefake.NewSimpleClientset([]runtime.Object{}...)
argoDBMock := dbmocks.ArgoDB{}
argoObjs := []runtime.Object{}
r := ApplicationSetReconciler{
@@ -3773,7 +3731,7 @@ func TestBuildAppDependencyList(t *testing.T) {
Scheme: scheme,
Recorder: record.NewFakeRecorder(1),
Generators: map[string]generators.Generator{},
ArgoDB: &argoDBMock,
ArgoDB: &dbmocks.ArgoDB{},
ArgoAppClientset: appclientset.NewSimpleClientset(argoObjs...),
KubeClientset: kubeclientset,
Metrics: metrics,
@@ -3791,9 +3749,6 @@ func TestBuildAppSyncMap(t *testing.T) {
err := v1alpha1.AddToScheme(scheme)
require.NoError(t, err)
err = v1alpha1.AddToScheme(scheme)
require.NoError(t, err)
client := fake.NewClientBuilder().WithScheme(scheme).Build()
metrics := appsetmetrics.NewFakeAppsetMetrics(client)
@@ -4437,7 +4392,6 @@ func TestBuildAppSyncMap(t *testing.T) {
} {
t.Run(cc.name, func(t *testing.T) {
kubeclientset := kubefake.NewSimpleClientset([]runtime.Object{}...)
argoDBMock := dbmocks.ArgoDB{}
argoObjs := []runtime.Object{}
r := ApplicationSetReconciler{
@@ -4445,7 +4399,7 @@ func TestBuildAppSyncMap(t *testing.T) {
Scheme: scheme,
Recorder: record.NewFakeRecorder(1),
Generators: map[string]generators.Generator{},
ArgoDB: &argoDBMock,
ArgoDB: &dbmocks.ArgoDB{},
ArgoAppClientset: appclientset.NewSimpleClientset(argoObjs...),
KubeClientset: kubeclientset,
Metrics: metrics,
@@ -4462,9 +4416,6 @@ func TestUpdateApplicationSetApplicationStatus(t *testing.T) {
err := v1alpha1.AddToScheme(scheme)
require.NoError(t, err)
err = v1alpha1.AddToScheme(scheme)
require.NoError(t, err)
for _, cc := range []struct {
name string
appSet v1alpha1.ApplicationSet
@@ -5387,7 +5338,6 @@ func TestUpdateApplicationSetApplicationStatus(t *testing.T) {
} {
t.Run(cc.name, func(t *testing.T) {
kubeclientset := kubefake.NewSimpleClientset([]runtime.Object{}...)
argoDBMock := dbmocks.ArgoDB{}
argoObjs := []runtime.Object{}
client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(&cc.appSet).WithStatusSubresource(&cc.appSet).Build()
@@ -5398,7 +5348,7 @@ func TestUpdateApplicationSetApplicationStatus(t *testing.T) {
Scheme: scheme,
Recorder: record.NewFakeRecorder(1),
Generators: map[string]generators.Generator{},
ArgoDB: &argoDBMock,
ArgoDB: &dbmocks.ArgoDB{},
ArgoAppClientset: appclientset.NewSimpleClientset(argoObjs...),
KubeClientset: kubeclientset,
Metrics: metrics,
@@ -5422,9 +5372,6 @@ func TestUpdateApplicationSetApplicationStatusProgress(t *testing.T) {
err := v1alpha1.AddToScheme(scheme)
require.NoError(t, err)
err = v1alpha1.AddToScheme(scheme)
require.NoError(t, err)
for _, cc := range []struct {
name string
appSet v1alpha1.ApplicationSet
@@ -6141,7 +6088,6 @@ func TestUpdateApplicationSetApplicationStatusProgress(t *testing.T) {
} {
t.Run(cc.name, func(t *testing.T) {
kubeclientset := kubefake.NewSimpleClientset([]runtime.Object{}...)
argoDBMock := dbmocks.ArgoDB{}
argoObjs := []runtime.Object{}
client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(&cc.appSet).WithStatusSubresource(&cc.appSet).Build()
@@ -6152,7 +6098,7 @@ func TestUpdateApplicationSetApplicationStatusProgress(t *testing.T) {
Scheme: scheme,
Recorder: record.NewFakeRecorder(1),
Generators: map[string]generators.Generator{},
ArgoDB: &argoDBMock,
ArgoDB: &dbmocks.ArgoDB{},
ArgoAppClientset: appclientset.NewSimpleClientset(argoObjs...),
KubeClientset: kubeclientset,
Metrics: metrics,
@@ -6176,9 +6122,6 @@ func TestUpdateResourceStatus(t *testing.T) {
err := v1alpha1.AddToScheme(scheme)
require.NoError(t, err)
err = v1alpha1.AddToScheme(scheme)
require.NoError(t, err)
for _, cc := range []struct {
name string
appSet v1alpha1.ApplicationSet
@@ -6357,7 +6300,6 @@ func TestUpdateResourceStatus(t *testing.T) {
} {
t.Run(cc.name, func(t *testing.T) {
kubeclientset := kubefake.NewSimpleClientset([]runtime.Object{}...)
argoDBMock := dbmocks.ArgoDB{}
argoObjs := []runtime.Object{}
client := fake.NewClientBuilder().WithScheme(scheme).WithStatusSubresource(&cc.appSet).WithObjects(&cc.appSet).Build()
@@ -6368,7 +6310,7 @@ func TestUpdateResourceStatus(t *testing.T) {
Scheme: scheme,
Recorder: record.NewFakeRecorder(1),
Generators: map[string]generators.Generator{},
ArgoDB: &argoDBMock,
ArgoDB: &dbmocks.ArgoDB{},
ArgoAppClientset: appclientset.NewSimpleClientset(argoObjs...),
KubeClientset: kubeclientset,
Metrics: metrics,
@@ -6424,8 +6366,6 @@ func TestResourceStatusAreOrdered(t *testing.T) {
err := v1alpha1.AddToScheme(scheme)
require.NoError(t, err)
err = v1alpha1.AddToScheme(scheme)
require.NoError(t, err)
for _, cc := range []struct {
name string
appSet v1alpha1.ApplicationSet
@@ -6449,7 +6389,6 @@ func TestResourceStatusAreOrdered(t *testing.T) {
} {
t.Run(cc.name, func(t *testing.T) {
kubeclientset := kubefake.NewSimpleClientset([]runtime.Object{}...)
argoDBMock := dbmocks.ArgoDB{}
argoObjs := []runtime.Object{}
client := fake.NewClientBuilder().WithScheme(scheme).WithStatusSubresource(&cc.appSet).WithObjects(&cc.appSet).Build()
@@ -6460,7 +6399,7 @@ func TestResourceStatusAreOrdered(t *testing.T) {
Scheme: scheme,
Recorder: record.NewFakeRecorder(1),
Generators: map[string]generators.Generator{},
ArgoDB: &argoDBMock,
ArgoDB: &dbmocks.ArgoDB{},
ArgoAppClientset: appclientset.NewSimpleClientset(argoObjs...),
KubeClientset: kubeclientset,
Metrics: metrics,
@@ -6677,9 +6616,6 @@ func TestMigrateStatus(t *testing.T) {
err := v1alpha1.AddToScheme(scheme)
require.NoError(t, err)
err = v1alpha1.AddToScheme(scheme)
require.NoError(t, err)
for _, tc := range []struct {
name string
appset v1alpha1.ApplicationSet
@@ -6742,3 +6678,86 @@ func TestMigrateStatus(t *testing.T) {
})
}
}
func TestIgnoreNotAllowedNamespaces(t *testing.T) {
tests := []struct {
name string
namespaces []string
objectNS string
expected bool
}{
{
name: "Namespace allowed",
namespaces: []string{"allowed-namespace"},
objectNS: "allowed-namespace",
expected: true,
},
{
name: "Namespace not allowed",
namespaces: []string{"allowed-namespace"},
objectNS: "not-allowed-namespace",
expected: false,
},
{
name: "Empty allowed namespaces",
namespaces: []string{},
objectNS: "any-namespace",
expected: false,
},
{
name: "Multiple allowed namespaces",
namespaces: []string{"allowed-namespace-1", "allowed-namespace-2"},
objectNS: "allowed-namespace-2",
expected: true,
},
{
name: "Namespace not in multiple allowed namespaces",
namespaces: []string{"allowed-namespace-1", "allowed-namespace-2"},
objectNS: "not-allowed-namespace",
expected: false,
},
{
name: "Namespace matched by glob pattern",
namespaces: []string{"allowed-namespace-*"},
objectNS: "allowed-namespace-1",
expected: true,
},
{
name: "Namespace matched by regex pattern",
namespaces: []string{"/^allowed-namespace-[^-]+$/"},
objectNS: "allowed-namespace-1",
expected: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
predicate := ignoreNotAllowedNamespaces(tt.namespaces)
object := &v1alpha1.ApplicationSet{
ObjectMeta: metav1.ObjectMeta{
Namespace: tt.objectNS,
},
}
t.Run(tt.name+":Create", func(t *testing.T) {
result := predicate.Create(event.CreateEvent{Object: object})
assert.Equal(t, tt.expected, result)
})
t.Run(tt.name+":Update", func(t *testing.T) {
result := predicate.Update(event.UpdateEvent{ObjectNew: object})
assert.Equal(t, tt.expected, result)
})
t.Run(tt.name+":Delete", func(t *testing.T) {
result := predicate.Delete(event.DeleteEvent{Object: object})
assert.Equal(t, tt.expected, result)
})
t.Run(tt.name+":Generic", func(t *testing.T) {
result := predicate.Generic(event.GenericEvent{Object: object})
assert.Equal(t, tt.expected, result)
})
})
}
}

View File

@@ -19,7 +19,7 @@ type BitbucketCloudPullRequest struct {
ID int `json:"id"`
Title string `json:"title"`
Source BitbucketCloudPullRequestSource `json:"source"`
Author string `json:"author"`
Author BitbucketCloudPullRequestAuthor `json:"author"`
}
type BitbucketCloudPullRequestSource struct {
@@ -35,6 +35,11 @@ type BitbucketCloudPullRequestSourceCommit struct {
Hash string `json:"hash"`
}
// Also have display_name and uuid, but don't plan to use them.
type BitbucketCloudPullRequestAuthor struct {
Nickname string `json:"nickname"`
}
type PullRequestResponse struct {
Page int32 `json:"page"`
Size int32 `json:"size"`
@@ -134,7 +139,7 @@ func (b *BitbucketCloudService) List(_ context.Context) ([]*PullRequest, error)
Title: pull.Title,
Branch: pull.Source.Branch.Name,
HeadSHA: pull.Source.Commit.Hash,
Author: pull.Author,
Author: pull.Author.Nickname,
})
}

View File

@@ -37,7 +37,9 @@ func defaultHandlerCloud(t *testing.T) func(http.ResponseWriter, *http.Request)
"hash": "1a8dd249c04a"
}
},
"author": "testName"
"author": {
"nickname": "testName"
}
}
]
}`)
@@ -154,7 +156,9 @@ func TestListPullRequestPaginationCloud(t *testing.T) {
"hash": "1a8dd249c04a"
}
},
"author": "testName"
"author": {
"nickname": "testName"
}
},
{
"id": 102,
@@ -168,7 +172,9 @@ func TestListPullRequestPaginationCloud(t *testing.T) {
"hash": "4cf807e67a6d"
}
},
"author": "testName"
"author": {
"nickname": "testName"
}
}
]
}`, r.Host))
@@ -191,7 +197,9 @@ func TestListPullRequestPaginationCloud(t *testing.T) {
"hash": "6344d9623e3b"
}
},
"author": "testName"
"author": {
"nickname": "testName"
}
}
]
}`, r.Host))
@@ -339,7 +347,9 @@ func TestListPullRequestBranchMatchCloud(t *testing.T) {
"hash": "1a8dd249c04a"
}
},
"author": "testName"
"author": {
"nickname": "testName"
}
},
{
"id": 200,
@@ -353,7 +363,9 @@ func TestListPullRequestBranchMatchCloud(t *testing.T) {
"hash": "4cf807e67a6d"
}
},
"author": "testName"
"author": {
"nickname": "testName"
}
}
]
}`, r.Host))
@@ -376,7 +388,9 @@ func TestListPullRequestBranchMatchCloud(t *testing.T) {
"hash": "6344d9623e3b"
}
},
"author": "testName"
"author": {
"nickname": "testName"
}
}
]
}`, r.Host))

View File

@@ -51,9 +51,12 @@ const (
// if we used destination name we infer the server url
// if we used both name and server then we return an invalid spec error
func ValidateDestination(ctx context.Context, dest *appv1.ApplicationDestination, clientset kubernetes.Interface, argoCDNamespace string) error {
if dest.IsServerInferred() && dest.IsNameInferred() {
return fmt.Errorf("application destination can't have both name and server inferred: %s %s", dest.Name, dest.Server)
}
if dest.Name != "" {
if dest.Server == "" {
server, err := getDestinationServer(ctx, dest.Name, clientset, argoCDNamespace)
server, err := getDestinationBy(ctx, dest.Name, clientset, argoCDNamespace, true)
if err != nil {
return fmt.Errorf("unable to find destination server: %w", err)
}
@@ -61,14 +64,25 @@ func ValidateDestination(ctx context.Context, dest *appv1.ApplicationDestination
return fmt.Errorf("application references destination cluster %s which does not exist", dest.Name)
}
dest.SetInferredServer(server)
} else if !dest.IsServerInferred() {
} else if !dest.IsServerInferred() && !dest.IsNameInferred() {
return fmt.Errorf("application destination can't have both name and server defined: %s %s", dest.Name, dest.Server)
}
} else if dest.Server != "" {
if dest.Name == "" {
serverName, err := getDestinationBy(ctx, dest.Server, clientset, argoCDNamespace, false)
if err != nil {
return fmt.Errorf("unable to find destination server: %w", err)
}
if serverName == "" {
return fmt.Errorf("application references destination cluster %s which does not exist", dest.Server)
}
dest.SetInferredName(serverName)
}
}
return nil
}
func getDestinationServer(ctx context.Context, clusterName string, clientset kubernetes.Interface, argoCDNamespace string) (string, error) {
func getDestinationBy(ctx context.Context, cluster string, clientset kubernetes.Interface, argoCDNamespace string, byName bool) (string, error) {
// settingsMgr := settings.NewSettingsManager(context.TODO(), clientset, namespace)
// argoDB := db.NewDB(namespace, settingsMgr, clientset)
// clusterList, err := argoDB.ListClusters(ctx)
@@ -78,14 +92,17 @@ func getDestinationServer(ctx context.Context, clusterName string, clientset kub
}
var servers []string
for _, c := range clusterList.Items {
if c.Name == clusterName {
if byName && c.Name == cluster {
servers = append(servers, c.Server)
}
if !byName && c.Server == cluster {
servers = append(servers, c.Name)
}
}
if len(servers) > 1 {
return "", fmt.Errorf("there are %d clusters with the same name: %v", len(servers), servers)
} else if len(servers) == 0 {
return "", fmt.Errorf("there are no clusters with this name: %s", clusterName)
return "", fmt.Errorf("there are no clusters with this name: %s", cluster)
}
return servers[0], nil
}

View File

@@ -92,7 +92,12 @@ func TestValidateDestination(t *testing.T) {
Namespace: "default",
}
appCond := ValidateDestination(context.Background(), &dest, nil, fakeNamespace)
secret := createClusterSecret("my-secret", "minikube", "https://127.0.0.1:6443")
objects := []runtime.Object{}
objects = append(objects, secret)
kubeclientset := fake.NewSimpleClientset(objects...)
appCond := ValidateDestination(context.Background(), &dest, kubeclientset, fakeNamespace)
require.NoError(t, appCond)
assert.False(t, dest.IsServerInferred())
})

33
assets/swagger.json generated
View File

@@ -1990,6 +1990,39 @@
}
}
},
"/api/v1/applicationsets/generate": {
"post": {
"tags": [
"ApplicationSetService"
],
"summary": "Generate generates",
"operationId": "ApplicationSetService_Generate",
"parameters": [
{
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/applicationsetApplicationSetGenerateRequest"
}
}
],
"responses": {
"200": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/applicationsetApplicationSetGenerateResponse"
}
},
"default": {
"description": "An unexpected error response.",
"schema": {
"$ref": "#/definitions/runtimeError"
}
}
}
}
},
"/api/v1/applicationsets/{name}": {
"get": {
"tags": [

View File

@@ -25,6 +25,7 @@ import (
appclientset "github.com/argoproj/argo-cd/v2/pkg/client/clientset/versioned"
"github.com/argoproj/argo-cd/v2/pkg/ratelimiter"
"github.com/argoproj/argo-cd/v2/reposerver/apiclient"
"github.com/argoproj/argo-cd/v2/util/argo"
"github.com/argoproj/argo-cd/v2/util/argo/normalizers"
cacheutil "github.com/argoproj/argo-cd/v2/util/cache"
appstatecache "github.com/argoproj/argo-cd/v2/util/cache/appstate"
@@ -82,6 +83,9 @@ func NewCommand() *cobra.Command {
enableDynamicClusterDistribution bool
serverSideDiff bool
ignoreNormalizerOpts normalizers.IgnoreNormalizerOpts
// argocd k8s event logging flag
enableK8sEvent []string
)
command := cobra.Command{
Use: cliName,
@@ -190,6 +194,7 @@ func NewCommand() *cobra.Command {
serverSideDiff,
enableDynamicClusterDistribution,
ignoreNormalizerOpts,
enableK8sEvent,
)
errors.CheckError(err)
cacheutil.CollectMetrics(redisClient, appController.GetMetricsServer())
@@ -267,6 +272,9 @@ func NewCommand() *cobra.Command {
command.Flags().BoolVar(&enableDynamicClusterDistribution, "dynamic-cluster-distribution-enabled", env.ParseBoolFromEnv(common.EnvEnableDynamicClusterDistribution, false), "Enables dynamic cluster distribution.")
command.Flags().BoolVar(&serverSideDiff, "server-side-diff-enabled", env.ParseBoolFromEnv(common.EnvServerSideDiff, false), "Feature flag to enable ServerSide diff. Default (\"false\")")
command.Flags().DurationVar(&ignoreNormalizerOpts.JQExecutionTimeout, "ignore-normalizer-jq-execution-timeout-seconds", env.ParseDurationFromEnv("ARGOCD_IGNORE_NORMALIZER_JQ_TIMEOUT", 0*time.Second, 0, math.MaxInt64), "Set ignore normalizer JQ execution timeout")
// argocd k8s event logging flag
command.Flags().StringSliceVar(&enableK8sEvent, "enable-k8s-event", env.StringsFromEnv("ARGOCD_ENABLE_K8S_EVENT", argo.DefaultEnableEventList(), ","), "Enable ArgoCD to use k8s event. For disabling all events, set the value as `none`. (e.g --enable-k8s-event=none), For enabling specific events, set the value as `event reason`. (e.g --enable-k8s-event=StatusRefreshed,ResourceCreated)")
cacheSource = appstatecache.AddCacheFlagsToCmd(&command, cacheutil.Options{
OnClientCreated: func(client *redis.Client) {
redisClient = client

View File

@@ -27,6 +27,7 @@ import (
reposervercache "github.com/argoproj/argo-cd/v2/reposerver/cache"
"github.com/argoproj/argo-cd/v2/server"
servercache "github.com/argoproj/argo-cd/v2/server/cache"
"github.com/argoproj/argo-cd/v2/util/argo"
cacheutil "github.com/argoproj/argo-cd/v2/util/cache"
"github.com/argoproj/argo-cd/v2/util/cli"
"github.com/argoproj/argo-cd/v2/util/dex"
@@ -91,6 +92,9 @@ func NewCommand() *cobra.Command {
scmRootCAPath string
allowedScmProviders []string
enableScmProviders bool
// argocd k8s event logging flag
enableK8sEvent []string
)
command := &cobra.Command{
Use: cliName,
@@ -151,6 +155,7 @@ func NewCommand() *cobra.Command {
controllerClient, err := client.New(config, client.Options{Scheme: scheme})
errors.CheckError(err)
controllerClient = client.NewDryRunClient(controllerClient)
controllerClient = client.NewNamespacedClient(controllerClient, namespace)
// Load CA information to use for validating connections to the
// repository server, if strict TLS validation was requested.
@@ -229,6 +234,7 @@ func NewCommand() *cobra.Command {
ApplicationNamespaces: applicationNamespaces,
EnableProxyExtension: enableProxyExtension,
WebhookParallelism: webhookParallelism,
EnableK8sEvent: enableK8sEvent,
}
appsetOpts := server.ApplicationSetOpts{
@@ -303,6 +309,7 @@ func NewCommand() *cobra.Command {
command.Flags().StringSliceVar(&applicationNamespaces, "application-namespaces", env.StringsFromEnv("ARGOCD_APPLICATION_NAMESPACES", []string{}, ","), "List of additional namespaces where application resources can be managed in")
command.Flags().BoolVar(&enableProxyExtension, "enable-proxy-extension", env.ParseBoolFromEnv("ARGOCD_SERVER_ENABLE_PROXY_EXTENSION", false), "Enable Proxy Extension feature")
command.Flags().IntVar(&webhookParallelism, "webhook-parallelism-limit", env.ParseNumFromEnv("ARGOCD_SERVER_WEBHOOK_PARALLELISM_LIMIT", 50, 1, 1000), "Number of webhook requests processed concurrently")
command.Flags().StringSliceVar(&enableK8sEvent, "enable-k8s-event", env.StringsFromEnv("ARGOCD_ENABLE_K8S_EVENT", argo.DefaultEnableEventList(), ","), "Enable ArgoCD to use k8s event. For disabling all events, set the value as `none`. (e.g --enable-k8s-event=none), For enabling specific events, set the value as `event reason`. (e.g --enable-k8s-event=StatusRefreshed,ResourceCreated)")
// Flags related to the applicationSet component.
command.Flags().StringVar(&scmRootCAPath, "appset-scm-root-ca-path", env.StringFromEnv("ARGOCD_APPLICATIONSET_CONTROLLER_SCM_ROOT_CA_PATH", ""), "Provide Root CA Path for self-signed TLS Certificates")

View File

@@ -379,7 +379,8 @@ func NewApplicationGetCommand(clientOpts *argocdclient.ClientOptions) *cobra.Com
})
errors.CheckError(err)
if app.Spec.HasMultipleSources() {
// check for source position if --show-params is set
if app.Spec.HasMultipleSources() && showParams {
if sourcePosition <= 0 {
errors.CheckError(fmt.Errorf("Source position should be specified and must be greater than 0 for applications with multiple sources"))
}

View File

@@ -14,8 +14,10 @@ import (
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/runtime"
corev1 "k8s.io/api/core/v1"
metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
runtimeUtil "k8s.io/apimachinery/pkg/util/runtime"
"k8s.io/client-go/dynamic"
"k8s.io/client-go/kubernetes"
cache2 "k8s.io/client-go/tools/cache"
@@ -127,7 +129,7 @@ func (c *forwardRepoClientset) NewRepoServerClient() (io.Closer, repoapiclient.R
}
repoServerName := c.repoServerName
repoServererviceLabelSelector := common.LabelKeyComponentRepoServer + "=" + common.LabelValueComponentRepoServer
repoServerServices, err := c.kubeClientset.CoreV1().Services(c.namespace).List(context.Background(), v1.ListOptions{LabelSelector: repoServererviceLabelSelector})
repoServerServices, err := c.kubeClientset.CoreV1().Services(c.namespace).List(context.Background(), metaV1.ListOptions{LabelSelector: repoServererviceLabelSelector})
if err != nil {
c.err = err
return
@@ -202,7 +204,7 @@ func MaybeStartLocalServer(ctx context.Context, clientOpts *apiclient.ClientOpti
}
// get rid of logging error handler
runtime.ErrorHandlers = runtime.ErrorHandlers[1:]
runtimeUtil.ErrorHandlers = runtimeUtil.ErrorHandlers[1:]
cli.SetLogLevel(log.ErrorLevel.String())
log.SetLevel(log.ErrorLevel)
os.Setenv(v1alpha1.EnvVarFakeInClusterConfig, "true")
@@ -237,7 +239,18 @@ func MaybeStartLocalServer(ctx context.Context, clientOpts *apiclient.ClientOpti
return fmt.Errorf("error creating kubernetes dynamic clientset: %w", err)
}
controllerClientset, err := client.New(restConfig, client.Options{})
scheme := runtime.NewScheme()
err = v1alpha1.AddToScheme(scheme)
if err != nil {
return fmt.Errorf("error adding argo resources to scheme: %w", err)
}
err = corev1.AddToScheme(scheme)
if err != nil {
return fmt.Errorf("error adding corev1 resources to scheme: %w", err)
}
controllerClientset, err := client.New(restConfig, client.Options{
Scheme: scheme,
})
if err != nil {
return fmt.Errorf("error creating kubernetes controller clientset: %w", err)
}

View File

@@ -4,9 +4,9 @@ import (
"os"
"path/filepath"
"github.com/spf13/cobra"
"github.com/argoproj/argo-cd/v2/cmd/util"
_ "go.uber.org/automaxprocs"
"github.com/spf13/cobra"
appcontroller "github.com/argoproj/argo-cd/v2/cmd/argocd-application-controller/commands"
applicationset "github.com/argoproj/argo-cd/v2/cmd/argocd-applicationset-controller/commands"
@@ -31,9 +31,12 @@ func main() {
if val := os.Getenv(binaryNameEnv); val != "" {
binaryName = val
}
isCLI := false
switch binaryName {
case "argocd", "argocd-linux-amd64", "argocd-darwin-amd64", "argocd-windows-amd64.exe":
command = cli.NewCommand()
isCLI = true
case "argocd-server":
command = apiserver.NewCommand()
case "argocd-application-controller":
@@ -42,19 +45,24 @@ func main() {
command = reposerver.NewCommand()
case "argocd-cmp-server":
command = cmpserver.NewCommand()
isCLI = true
case "argocd-dex":
command = dex.NewCommand()
case "argocd-notifications":
command = notification.NewCommand()
case "argocd-git-ask-pass":
command = gitaskpass.NewCommand()
isCLI = true
case "argocd-applicationset-controller":
command = applicationset.NewCommand()
case "argocd-k8s-auth":
command = k8sauth.NewCommand()
isCLI = true
default:
command = cli.NewCommand()
isCLI = true
}
util.SetAutoMaxProcs(isCLI)
if err := command.Execute(); err != nil {
os.Exit(1)

View File

@@ -9,6 +9,8 @@ import (
"strings"
"time"
"go.uber.org/automaxprocs/maxprocs"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"github.com/argoproj/gitops-engine/pkg/utils/kube"
@@ -88,6 +90,19 @@ type AppOptions struct {
ref string
}
// SetAutoMaxProcs sets the GOMAXPROCS value based on the binary name.
// It suppresses logs for CLI binaries and logs the setting for services.
func SetAutoMaxProcs(isCLI bool) {
if isCLI {
_, _ = maxprocs.Set() // Intentionally ignore errors for CLI binaries
} else {
_, err := maxprocs.Set(maxprocs.Logger(log.Infof))
if err != nil {
log.Errorf("Error setting GOMAXPROCS: %v", err)
}
}
}
func AddAppFlags(command *cobra.Command, opts *AppOptions) {
command.Flags().StringVar(&opts.repoURL, "repo", "", "Repository URL, ignored if a file is set")
command.Flags().StringVar(&opts.appPath, "path", "", "Path in repository to the app directory, ignored if a file is set")

View File

@@ -1,10 +1,11 @@
package util
import (
"bytes"
"log"
"os"
"testing"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -529,3 +530,27 @@ func TestFilterResources(t *testing.T) {
assert.Nil(t, filteredResources)
})
}
func TestSetAutoMaxProcs(t *testing.T) {
t.Run("CLI mode ignores errors", func(t *testing.T) {
logBuffer := &bytes.Buffer{}
oldLogger := log.Default()
log.SetOutput(logBuffer)
defer log.SetOutput(oldLogger.Writer())
SetAutoMaxProcs(true)
assert.Empty(t, logBuffer.String(), "Expected no log output when isCLI is true")
})
t.Run("Non-CLI mode logs error on failure", func(t *testing.T) {
logBuffer := &bytes.Buffer{}
oldLogger := log.Default()
log.SetOutput(logBuffer)
defer log.SetOutput(oldLogger.Writer())
SetAutoMaxProcs(false)
assert.NotContains(t, logBuffer.String(), "Error setting GOMAXPROCS", "Unexpected log output detected")
})
}

View File

@@ -175,6 +175,7 @@ func NewApplicationController(
serverSideDiff bool,
dynamicClusterDistributionEnabled bool,
ignoreNormalizerOpts normalizers.IgnoreNormalizerOpts,
enableK8sEvent []string,
) (*ApplicationController, error) {
log.Infof("appResyncPeriod=%v, appHardResyncPeriod=%v, appResyncJitter=%v", appResyncPeriod, appHardResyncPeriod, appResyncJitter)
db := db.NewDB(namespace, settingsMgr, kubeClientset)
@@ -199,7 +200,7 @@ func NewApplicationController(
statusRefreshJitter: appResyncJitter,
refreshRequestedApps: make(map[string]CompareWith),
refreshRequestedAppsMutex: &sync.Mutex{},
auditLogger: argo.NewAuditLogger(namespace, kubeClientset, common.ApplicationController),
auditLogger: argo.NewAuditLogger(namespace, kubeClientset, common.ApplicationController, enableK8sEvent),
settingsMgr: settingsMgr,
selfHealTimeout: selfHealTimeout,
selfHealBackOff: selfHealBackoff,

View File

@@ -45,12 +45,15 @@ import (
"github.com/argoproj/argo-cd/v2/reposerver/apiclient"
mockrepoclient "github.com/argoproj/argo-cd/v2/reposerver/apiclient/mocks"
"github.com/argoproj/argo-cd/v2/test"
"github.com/argoproj/argo-cd/v2/util/argo"
"github.com/argoproj/argo-cd/v2/util/argo/normalizers"
cacheutil "github.com/argoproj/argo-cd/v2/util/cache"
appstatecache "github.com/argoproj/argo-cd/v2/util/cache/appstate"
"github.com/argoproj/argo-cd/v2/util/settings"
)
var testEnableEventList []string = argo.DefaultEnableEventList()
type namespacedResource struct {
v1alpha1.ResourceNode
AppName string
@@ -170,6 +173,7 @@ func newFakeController(data *fakeData, repoErr error) *ApplicationController {
false,
false,
normalizers.IgnoreNormalizerOpts{},
testEnableEventList,
)
db := &dbmocks.ArgoDB{}
db.On("GetApplicationControllerReplicas").Return(1)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 117 KiB

After

Width:  |  Height:  |  Size: 163 KiB

View File

@@ -31,6 +31,7 @@ argocd-application-controller [flags]
--default-cache-expiration duration Cache expiration default (default 24h0m0s)
--disable-compression If true, opt-out of response compression for all requests to the server
--dynamic-cluster-distribution-enabled Enables dynamic cluster distribution.
--enable-k8s-event none Enable ArgoCD to use k8s event. For disabling all events, set the value as none. (e.g --enable-k8s-event=none), For enabling specific events, set the value as `event reason`. (e.g --enable-k8s-event=StatusRefreshed,ResourceCreated) (default [all])
--gloglevel int Set the glog logging level
-h, --help help for argocd-application-controller
--ignore-normalizer-jq-execution-timeout-seconds duration Set ignore normalizer JQ execution timeout

View File

@@ -51,6 +51,7 @@ argocd-server [flags]
--disable-auth Disable client authentication
--disable-compression If true, opt-out of response compression for all requests to the server
--enable-gzip Enable GZIP compression (default true)
--enable-k8s-event none Enable ArgoCD to use k8s event. For disabling all events, set the value as none. (e.g --enable-k8s-event=none), For enabling specific events, set the value as `event reason`. (e.g --enable-k8s-event=StatusRefreshed,ResourceCreated) (default [all])
--enable-proxy-extension Enable Proxy Extension feature
--gloglevel int Set the glog logging level
-h, --help help for argocd-server

32
go.mod
View File

@@ -10,7 +10,7 @@ require (
github.com/TomOnTime/utfutil v0.0.0-20180511104225-09c41003ee1d
github.com/alicebob/miniredis/v2 v2.33.0
github.com/antonmedv/expr v1.15.1
github.com/argoproj/gitops-engine v0.7.1-0.20240905010810-bd7681ae3f8b
github.com/argoproj/gitops-engine v0.7.1-0.20250129155113-4c6e03c46314
github.com/argoproj/notifications-engine v0.4.1-0.20240606074338-0802cd427621
github.com/argoproj/pkg v0.13.7-0.20230626144333-d56162821bd1
github.com/aws/aws-sdk-go v1.55.5
@@ -22,14 +22,14 @@ require (
github.com/cespare/xxhash/v2 v2.3.0
github.com/chainguard-dev/git-urls v1.0.2
github.com/coreos/go-oidc/v3 v3.11.0
github.com/cyphar/filepath-securejoin v0.3.2
github.com/cyphar/filepath-securejoin v0.3.6
github.com/dustin/go-humanize v1.0.1
github.com/evanphx/json-patch v5.9.0+incompatible
github.com/expr-lang/expr v1.16.9
github.com/felixge/httpsnoop v1.0.4
github.com/fsnotify/fsnotify v1.7.0
github.com/gfleury/go-bitbucket-v1 v0.0.0-20220301131131-8e7ed04b843e
github.com/go-git/go-git/v5 v5.12.0
github.com/go-git/go-git/v5 v5.13.1
github.com/go-jose/go-jose/v3 v3.0.3
github.com/go-logr/logr v1.4.2
github.com/go-openapi/loads v0.22.0
@@ -75,7 +75,7 @@ require (
github.com/soheilhy/cmux v0.1.5
github.com/spf13/cobra v1.8.1
github.com/spf13/pflag v1.0.5
github.com/stretchr/testify v1.9.0
github.com/stretchr/testify v1.10.0
github.com/valyala/fasttemplate v1.2.2
github.com/xanzy/go-gitlab v0.109.0
github.com/yuin/gopher-lua v1.1.1
@@ -83,12 +83,12 @@ require (
go.opentelemetry.io/otel v1.30.0
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.30.0
go.opentelemetry.io/otel/sdk v1.30.0
golang.org/x/crypto v0.27.0
golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1
golang.org/x/net v0.29.0
golang.org/x/crypto v0.31.0
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56
golang.org/x/net v0.33.0
golang.org/x/oauth2 v0.23.0
golang.org/x/sync v0.8.0
golang.org/x/term v0.24.0
golang.org/x/sync v0.10.0
golang.org/x/term v0.27.0
golang.org/x/time v0.6.0
google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1
google.golang.org/grpc v1.66.2
@@ -149,10 +149,10 @@ require (
github.com/x448/float16 v0.8.4 // indirect
go.opencensus.io v0.24.0 // indirect
go.starlark.net v0.0.0-20230525235612-a134d8f9ddca // indirect
golang.org/x/mod v0.17.0 // indirect
golang.org/x/sys v0.25.0 // indirect
golang.org/x/text v0.18.0 // indirect
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect
golang.org/x/mod v0.19.0 // indirect
golang.org/x/sys v0.28.0 // indirect
golang.org/x/text v0.21.0 // indirect
golang.org/x/tools v0.23.0 // indirect
google.golang.org/api v0.132.0 // indirect
google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 // indirect
@@ -176,7 +176,7 @@ require (
github.com/Masterminds/goutils v1.1.1 // indirect
github.com/Microsoft/go-winio v0.6.1 // indirect
github.com/PagerDuty/go-pagerduty v1.7.0 // indirect
github.com/ProtonMail/go-crypto v1.0.0 // indirect
github.com/ProtonMail/go-crypto v1.1.3 // indirect
github.com/RocketChat/Rocket.Chat.Go.SDK v0.0.0-20210112200207-10ab4d695d60 // indirect
github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a // indirect
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
@@ -198,7 +198,7 @@ require (
github.com/ghodss/yaml v1.0.0 // indirect
github.com/go-errors/errors v1.4.2 // indirect
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
github.com/go-git/go-billy/v5 v5.5.0 // indirect
github.com/go-git/go-billy/v5 v5.6.1 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-openapi/analysis v0.23.0 // indirect
github.com/go-openapi/errors v0.22.0 // indirect
@@ -260,7 +260,7 @@ require (
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect
github.com/shopspring/decimal v1.4.0 // indirect
github.com/skeema/knownhosts v1.2.2 // indirect
github.com/skeema/knownhosts v1.3.0 // indirect
github.com/slack-go/slack v0.12.2 // indirect
github.com/spf13/cast v1.7.0 // indirect
github.com/stretchr/objx v0.5.2 // indirect

76
go.sum
View File

@@ -56,8 +56,8 @@ github.com/OvyFlash/telegram-bot-api/v5 v5.0.0-20240108230938-63e5c59035bf h1:a7
github.com/OvyFlash/telegram-bot-api/v5 v5.0.0-20240108230938-63e5c59035bf/go.mod h1:A2S0CWkNylc2phvKXWBBdD3K0iGnDBGbzRpISP2zBl8=
github.com/PagerDuty/go-pagerduty v1.7.0 h1:S1NcMKECxT5hJwV4VT+QzeSsSiv4oWl1s2821dUqG/8=
github.com/PagerDuty/go-pagerduty v1.7.0/go.mod h1:PuFyJKRz1liIAH4h5KVXVD18Obpp1ZXRdxHvmGXooro=
github.com/ProtonMail/go-crypto v1.0.0 h1:LRuvITjQWX+WIfr930YHG2HNfjR1uOfyf5vE0kC2U78=
github.com/ProtonMail/go-crypto v1.0.0/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0=
github.com/ProtonMail/go-crypto v1.1.3 h1:nRBOetoydLeUb4nHajyO2bKqMLfWQ/ZPwkXqXxPxCFk=
github.com/ProtonMail/go-crypto v1.1.3/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE=
github.com/RocketChat/Rocket.Chat.Go.SDK v0.0.0-20210112200207-10ab4d695d60 h1:prBTRx78AQnXzivNT9Crhu564W/zPPr3ibSlpT9xKcE=
github.com/RocketChat/Rocket.Chat.Go.SDK v0.0.0-20210112200207-10ab4d695d60/go.mod h1:rjP7sIipbZcagro/6TCk6X0ZeFT2eyudH5+fve/cbBA=
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
@@ -83,8 +83,8 @@ github.com/antonmedv/expr v1.15.1/go.mod h1:0E/6TxnOlRNp81GMzX9QfDPAmHo2Phg00y4J
github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
github.com/appscode/go v0.0.0-20191119085241-0887d8ec2ecc/go.mod h1:OawnOmAL4ZX3YaPdN+8HTNwBveT1jMsqP74moa9XUbE=
github.com/argoproj/gitops-engine v0.7.1-0.20240905010810-bd7681ae3f8b h1:wOPWJ5MBScQO767WpU55oUJDXObfvPL0EfAYWxogbSw=
github.com/argoproj/gitops-engine v0.7.1-0.20240905010810-bd7681ae3f8b/go.mod h1:b1vuwkyMUszyUK+USUJqC8vJijnQsEPNDpC+sDdDLtM=
github.com/argoproj/gitops-engine v0.7.1-0.20250129155113-4c6e03c46314 h1:UIM6b4b/eNmWLwnsaJNmLzcm0qjHCuyHTuJKeIq2WeE=
github.com/argoproj/gitops-engine v0.7.1-0.20250129155113-4c6e03c46314/go.mod h1:b1vuwkyMUszyUK+USUJqC8vJijnQsEPNDpC+sDdDLtM=
github.com/argoproj/notifications-engine v0.4.1-0.20240606074338-0802cd427621 h1:Yg1nt+D2uDK1SL2jSlfukA4yc7db184TTN7iWy3voRE=
github.com/argoproj/notifications-engine v0.4.1-0.20240606074338-0802cd427621/go.mod h1:N0A4sEws2soZjEpY4hgZpQS8mRIEw6otzwfkgc3g9uQ=
github.com/argoproj/pkg v0.13.7-0.20230626144333-d56162821bd1 h1:qsHwwOJ21K2Ao0xPju1sNuqphyMnMYkyB3ZLoLtxWpo=
@@ -151,7 +151,6 @@ github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs=
github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c=
github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA=
github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0=
github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0=
github.com/bwmarrin/discordgo v0.19.0/go.mod h1:O9S4p+ofTFwB02em7jkpkV8M3R0/PUVOwN61zSZ0r4Q=
github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ=
github.com/casbin/casbin/v2 v2.99.0 h1:Y993vfRenh8Xtb4XVaK8KeYJTjD4Zn1XVewGszhzk1E=
@@ -183,7 +182,6 @@ github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMn
github.com/chzyer/test v1.0.0/go.mod h1:2JlltgoNkt4TW/z9V/IzDdFaMTM2JPIi26O1pF38GC8=
github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA=
github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU=
github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
@@ -204,8 +202,8 @@ github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7Do
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY=
github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
github.com/cyphar/filepath-securejoin v0.3.2 h1:QhZu5AxQ+o1XZH0Ye05YzvJ0kAdK6VQc0z9NNMek7gc=
github.com/cyphar/filepath-securejoin v0.3.2/go.mod h1:F7i41x/9cBF7lzCrVsYs9fuzwRZm4NQsGTBdpp6mETc=
github.com/cyphar/filepath-securejoin v0.3.6 h1:4d9N5ykBnSp5Xn2JkhocYDkOpURL/18CYMpo6xB9uWM=
github.com/cyphar/filepath-securejoin v0.3.6/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
@@ -231,8 +229,8 @@ github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5m
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a h1:mATvB/9r/3gvcejNsXKSkQ6lcIaNec2nyfOdlTBR2lU=
github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM=
github.com/elazarl/goproxy v1.2.3 h1:xwIyKHbaP5yfT6O9KIeYJR5549MXRQkoQMRXGztz8YQ=
github.com/elazarl/goproxy v1.2.3/go.mod h1:YfEbZtqP4AetfO6d40vWchF3znWX7C7Vd6ZMfdL8z64=
github.com/emicklei/go-restful/v3 v3.8.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g=
github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
@@ -281,20 +279,20 @@ github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
github.com/gin-gonic/gin v1.6.3 h1:ahKqKTFpO5KTPHxWZjEdPScmYaGtLo8Y4DMHoEsnp14=
github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M=
github.com/gliderlabs/ssh v0.3.7 h1:iV3Bqi942d9huXnzEF2Mt+CY9gLu8DNM4Obd+8bODRE=
github.com/gliderlabs/ssh v0.3.7/go.mod h1:zpHEXBstFnQYtGnB8k8kQLol82umzn/2/snG7alWVD8=
github.com/gliderlabs/ssh v0.3.8 h1:a4YXD1V7xMF9g5nTkdfnja3Sxy1PVDCj1Zg4Wb8vY6c=
github.com/gliderlabs/ssh v0.3.8/go.mod h1:xYoytBv1sV0aL3CavoDuJIQNURXkkfPA/wxQ1pL1fAU=
github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA=
github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og=
github.com/go-fed/httpsig v1.1.0 h1:9M+hb0jkEICD8/cAiNqEB66R87tTINszBRTjwjQzWcI=
github.com/go-fed/httpsig v1.1.0/go.mod h1:RCMrTZvN1bJYtofsG4rd5NaO5obxQ5xBkdiS7xsT7bM=
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI=
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic=
github.com/go-git/go-billy/v5 v5.5.0 h1:yEY4yhzCDuMGSv83oGxiBotRzhwhNr8VZyphhiu+mTU=
github.com/go-git/go-billy/v5 v5.5.0/go.mod h1:hmexnoNsr2SJU1Ju67OaNz5ASJY3+sHgFRpCtpDCKow=
github.com/go-git/go-billy/v5 v5.6.1 h1:u+dcrgaguSSkbjzHwelEjc0Yj300NUevrrPphk/SoRA=
github.com/go-git/go-billy/v5 v5.6.1/go.mod h1:0AsLr1z2+Uksi4NlElmMblP5rPcDZNRCD8ujZCRR2BE=
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4=
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII=
github.com/go-git/go-git/v5 v5.12.0 h1:7Md+ndsjrzZxbddRDZjF14qK+NN56sy6wkqaVrjZtys=
github.com/go-git/go-git/v5 v5.12.0/go.mod h1:FTM9VKtnI2m65hNI/TenDDDnUf2Q9FHnXYjuz9i5OEY=
github.com/go-git/go-git/v5 v5.13.1 h1:DAQ9APonnlvSWpvolXWIuV6Q6zXy2wHbN4cVlNR5Q+M=
github.com/go-git/go-git/v5 v5.13.1/go.mod h1:qryJB4cSBoq3FRoBRf5A77joojuBcmPJ0qu3XXXVixc=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-jose/go-jose/v3 v3.0.3 h1:fFKWeig/irsp7XD2zBxvnmA/XaRWp5V3CBsZXJF7G7k=
github.com/go-jose/go-jose/v3 v3.0.3/go.mod h1:5b+7YgP7ZICgJDBdfjZaIt+H/9L9T/YQrVfLAMboGkQ=
@@ -764,8 +762,9 @@ github.com/onsi/gomega v1.27.8/go.mod h1:2J8vzI/s+2shY9XHRApDkdgPo1TKT7P2u6fXeJK
github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M=
github.com/onsi/gomega v1.30.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ=
github.com/onsi/gomega v1.33.0/go.mod h1:+925n5YtiFsLzzafLUHzVMBpvvRAzrydIBiSIxjX3wY=
github.com/onsi/gomega v1.33.1 h1:dsYjIxxSR755MDmKVsaFQTE22ChNBcuuTWgkUDSubOk=
github.com/onsi/gomega v1.33.1/go.mod h1:U4R44UsT+9eLIaYRB2a5qajjtQYn0hauxvRm16AVYg0=
github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k=
github.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeDLwwY=
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
@@ -882,8 +881,8 @@ github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic
github.com/sirupsen/logrus v1.9.2/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/skeema/knownhosts v1.2.2 h1:Iug2P4fLmDw9f41PB6thxUkNUkJzB5i+1/exaj40L3A=
github.com/skeema/knownhosts v1.2.2/go.mod h1:xYbVRSPxqBZFrdmDyMmsOs+uX1UZC3nTN3ThzgDxUwo=
github.com/skeema/knownhosts v1.3.0 h1:AM+y0rI04VksttfwjkSTNQorvGqmwATnvnAHpSgc0LY=
github.com/skeema/knownhosts v1.3.0/go.mod h1:sPINvnADmT/qYH1kfv+ePMmOBTH6Tbl7b5LvTDjFK7M=
github.com/skratchdot/open-golang v0.0.0-20160302144031-75fb7ed4208c h1:fyKiXKO1/I/B6Y2U8T7WdQGWzwehOuGIrljPtt7YTTI=
github.com/skratchdot/open-golang v0.0.0-20160302144031-75fb7ed4208c/go.mod h1:sUM3LWHvSMaG192sy56D9F7CNvL7jUJVXoqM1QKLnog=
github.com/slack-go/slack v0.12.2 h1:x3OppyMyGIbbiyFhsBmpf9pwkUzMhthJMRNmNlA4LaQ=
@@ -928,8 +927,9 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo=
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
@@ -1024,9 +1024,7 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw=
golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0=
golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I=
golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio=
@@ -1040,13 +1038,13 @@ golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOM
golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M=
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM=
golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A=
golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70=
golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U=
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw=
golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 h1:k/i9J1pBpvlfR+9QsetwPyERsqu1GIbi967PQMq3Ivc=
golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w=
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8=
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
@@ -1070,8 +1068,9 @@ golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA=
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8=
golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -1125,8 +1124,8 @@ golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8=
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE=
golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo=
golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0=
golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I=
golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -1150,8 +1149,8 @@ golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ=
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -1222,8 +1221,8 @@ golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34=
golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/telemetry v0.0.0-20240208230135-b75ee8823808/go.mod h1:KG1lNk5ZFNssSZLrpVb4sMXKMpGwGXOxSG3rnu2gZQQ=
golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
@@ -1248,8 +1247,8 @@ golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58=
golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk=
golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0=
golang.org/x/term v0.24.0 h1:Mh5cbb+Zk2hqqXNO7S1iTjEphVL+jb8ZWaqh/g+JWkM=
golang.org/x/term v0.24.0/go.mod h1:lOBK/LVxemqiMij05LGJ0tzNr8xlmwBRJ81PX6wVLH8=
golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q=
golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
@@ -1269,8 +1268,8 @@ golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224=
golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@@ -1311,8 +1310,9 @@ golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps
golang.org/x/tools v0.18.0/go.mod h1:GL7B4CwcLLeo59yx/9UWWuNOW1n3VZ4f5axWfML7Lcg=
golang.org/x/tools v0.20.0/go.mod h1:WvitBU7JJf6A4jOdg4S1tviW9bhUxkgeCui/0JHctQg=
golang.org/x/tools v0.21.0/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg=
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg=
golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=

View File

@@ -5,7 +5,7 @@ kind: Kustomization
images:
- name: quay.io/argoproj/argocd
newName: quay.io/argoproj/argocd
newTag: v2.13.0
newTag: v2.13.4
resources:
- ./application-controller
- ./dex

View File

@@ -15,7 +15,6 @@ rules:
- delete # supports deletion a live object in UI
- get # supports viewing live object manifest in UI
- patch # supports `argocd app patch`
- list # supports `argocd appset generate` with cluster generator
- apiGroups:
- ""
resources:

View File

@@ -22571,7 +22571,7 @@ spec:
key: applicationsetcontroller.webhook.parallelism.limit
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.13.0
image: quay.io/argoproj/argocd:v2.13.4
imagePullPolicy: Always
name: argocd-applicationset-controller
ports:
@@ -22689,7 +22689,7 @@ spec:
- argocd
- admin
- redis-initial-password
image: quay.io/argoproj/argocd:v2.13.0
image: quay.io/argoproj/argocd:v2.13.4
imagePullPolicy: IfNotPresent
name: secret-init
securityContext:
@@ -22942,7 +22942,7 @@ spec:
value: /helm-working-dir
- name: HELM_DATA_HOME
value: /helm-working-dir
image: quay.io/argoproj/argocd:v2.13.0
image: quay.io/argoproj/argocd:v2.13.4
imagePullPolicy: Always
livenessProbe:
failureThreshold: 3
@@ -22994,7 +22994,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /var/run/argocd/argocd-cmp-server
image: quay.io/argoproj/argocd:v2.13.0
image: quay.io/argoproj/argocd:v2.13.4
name: copyutil
securityContext:
allowPrivilegeEscalation: false
@@ -23284,7 +23284,7 @@ spec:
key: controller.ignore.normalizer.jq.timeout
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.13.0
image: quay.io/argoproj/argocd:v2.13.4
imagePullPolicy: Always
name: argocd-application-controller
ports:

View File

@@ -12,4 +12,4 @@ resources:
images:
- name: quay.io/argoproj/argocd
newName: quay.io/argoproj/argocd
newTag: v2.13.0
newTag: v2.13.4

View File

@@ -12,7 +12,7 @@ patches:
images:
- name: quay.io/argoproj/argocd
newName: quay.io/argoproj/argocd
newTag: v2.13.0
newTag: v2.13.4
resources:
- ../../base/application-controller
- ../../base/applicationset-controller

View File

@@ -22476,7 +22476,6 @@ rules:
- delete
- get
- patch
- list
- apiGroups:
- ""
resources:
@@ -23915,7 +23914,7 @@ spec:
key: applicationsetcontroller.webhook.parallelism.limit
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.13.0
image: quay.io/argoproj/argocd:v2.13.4
imagePullPolicy: Always
name: argocd-applicationset-controller
ports:
@@ -24050,7 +24049,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /shared/argocd-dex
image: quay.io/argoproj/argocd:v2.13.0
image: quay.io/argoproj/argocd:v2.13.4
imagePullPolicy: Always
name: copyutil
securityContext:
@@ -24138,7 +24137,7 @@ spec:
key: notificationscontroller.repo.server.plaintext
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.13.0
image: quay.io/argoproj/argocd:v2.13.4
imagePullPolicy: Always
livenessProbe:
tcpSocket:
@@ -24257,7 +24256,7 @@ spec:
- argocd
- admin
- redis-initial-password
image: quay.io/argoproj/argocd:v2.13.0
image: quay.io/argoproj/argocd:v2.13.4
imagePullPolicy: IfNotPresent
name: secret-init
securityContext:
@@ -24538,7 +24537,7 @@ spec:
value: /helm-working-dir
- name: HELM_DATA_HOME
value: /helm-working-dir
image: quay.io/argoproj/argocd:v2.13.0
image: quay.io/argoproj/argocd:v2.13.4
imagePullPolicy: Always
livenessProbe:
failureThreshold: 3
@@ -24590,7 +24589,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /var/run/argocd/argocd-cmp-server
image: quay.io/argoproj/argocd:v2.13.0
image: quay.io/argoproj/argocd:v2.13.4
name: copyutil
securityContext:
allowPrivilegeEscalation: false
@@ -24944,7 +24943,7 @@ spec:
key: applicationsetcontroller.enable.scm.providers
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.13.0
image: quay.io/argoproj/argocd:v2.13.4
imagePullPolicy: Always
livenessProbe:
httpGet:
@@ -25270,7 +25269,7 @@ spec:
key: controller.ignore.normalizer.jq.timeout
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.13.0
image: quay.io/argoproj/argocd:v2.13.4
imagePullPolicy: Always
name: argocd-application-controller
ports:

View File

@@ -1694,7 +1694,7 @@ spec:
key: applicationsetcontroller.webhook.parallelism.limit
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.13.0
image: quay.io/argoproj/argocd:v2.13.4
imagePullPolicy: Always
name: argocd-applicationset-controller
ports:
@@ -1829,7 +1829,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /shared/argocd-dex
image: quay.io/argoproj/argocd:v2.13.0
image: quay.io/argoproj/argocd:v2.13.4
imagePullPolicy: Always
name: copyutil
securityContext:
@@ -1917,7 +1917,7 @@ spec:
key: notificationscontroller.repo.server.plaintext
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.13.0
image: quay.io/argoproj/argocd:v2.13.4
imagePullPolicy: Always
livenessProbe:
tcpSocket:
@@ -2036,7 +2036,7 @@ spec:
- argocd
- admin
- redis-initial-password
image: quay.io/argoproj/argocd:v2.13.0
image: quay.io/argoproj/argocd:v2.13.4
imagePullPolicy: IfNotPresent
name: secret-init
securityContext:
@@ -2317,7 +2317,7 @@ spec:
value: /helm-working-dir
- name: HELM_DATA_HOME
value: /helm-working-dir
image: quay.io/argoproj/argocd:v2.13.0
image: quay.io/argoproj/argocd:v2.13.4
imagePullPolicy: Always
livenessProbe:
failureThreshold: 3
@@ -2369,7 +2369,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /var/run/argocd/argocd-cmp-server
image: quay.io/argoproj/argocd:v2.13.0
image: quay.io/argoproj/argocd:v2.13.4
name: copyutil
securityContext:
allowPrivilegeEscalation: false
@@ -2723,7 +2723,7 @@ spec:
key: applicationsetcontroller.enable.scm.providers
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.13.0
image: quay.io/argoproj/argocd:v2.13.4
imagePullPolicy: Always
livenessProbe:
httpGet:
@@ -3049,7 +3049,7 @@ spec:
key: controller.ignore.normalizer.jq.timeout
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.13.0
image: quay.io/argoproj/argocd:v2.13.4
imagePullPolicy: Always
name: argocd-application-controller
ports:

17
manifests/install.yaml generated
View File

@@ -22443,7 +22443,6 @@ rules:
- delete
- get
- patch
- list
- apiGroups:
- ""
resources:
@@ -23032,7 +23031,7 @@ spec:
key: applicationsetcontroller.webhook.parallelism.limit
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.13.0
image: quay.io/argoproj/argocd:v2.13.4
imagePullPolicy: Always
name: argocd-applicationset-controller
ports:
@@ -23167,7 +23166,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /shared/argocd-dex
image: quay.io/argoproj/argocd:v2.13.0
image: quay.io/argoproj/argocd:v2.13.4
imagePullPolicy: Always
name: copyutil
securityContext:
@@ -23255,7 +23254,7 @@ spec:
key: notificationscontroller.repo.server.plaintext
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.13.0
image: quay.io/argoproj/argocd:v2.13.4
imagePullPolicy: Always
livenessProbe:
tcpSocket:
@@ -23355,7 +23354,7 @@ spec:
- argocd
- admin
- redis-initial-password
image: quay.io/argoproj/argocd:v2.13.0
image: quay.io/argoproj/argocd:v2.13.4
imagePullPolicy: IfNotPresent
name: secret-init
securityContext:
@@ -23608,7 +23607,7 @@ spec:
value: /helm-working-dir
- name: HELM_DATA_HOME
value: /helm-working-dir
image: quay.io/argoproj/argocd:v2.13.0
image: quay.io/argoproj/argocd:v2.13.4
imagePullPolicy: Always
livenessProbe:
failureThreshold: 3
@@ -23660,7 +23659,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /var/run/argocd/argocd-cmp-server
image: quay.io/argoproj/argocd:v2.13.0
image: quay.io/argoproj/argocd:v2.13.4
name: copyutil
securityContext:
allowPrivilegeEscalation: false
@@ -24012,7 +24011,7 @@ spec:
key: applicationsetcontroller.enable.scm.providers
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.13.0
image: quay.io/argoproj/argocd:v2.13.4
imagePullPolicy: Always
livenessProbe:
httpGet:
@@ -24338,7 +24337,7 @@ spec:
key: controller.ignore.normalizer.jq.timeout
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.13.0
image: quay.io/argoproj/argocd:v2.13.4
imagePullPolicy: Always
name: argocd-application-controller
ports:

View File

@@ -811,7 +811,7 @@ spec:
key: applicationsetcontroller.webhook.parallelism.limit
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.13.0
image: quay.io/argoproj/argocd:v2.13.4
imagePullPolicy: Always
name: argocd-applicationset-controller
ports:
@@ -946,7 +946,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /shared/argocd-dex
image: quay.io/argoproj/argocd:v2.13.0
image: quay.io/argoproj/argocd:v2.13.4
imagePullPolicy: Always
name: copyutil
securityContext:
@@ -1034,7 +1034,7 @@ spec:
key: notificationscontroller.repo.server.plaintext
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.13.0
image: quay.io/argoproj/argocd:v2.13.4
imagePullPolicy: Always
livenessProbe:
tcpSocket:
@@ -1134,7 +1134,7 @@ spec:
- argocd
- admin
- redis-initial-password
image: quay.io/argoproj/argocd:v2.13.0
image: quay.io/argoproj/argocd:v2.13.4
imagePullPolicy: IfNotPresent
name: secret-init
securityContext:
@@ -1387,7 +1387,7 @@ spec:
value: /helm-working-dir
- name: HELM_DATA_HOME
value: /helm-working-dir
image: quay.io/argoproj/argocd:v2.13.0
image: quay.io/argoproj/argocd:v2.13.4
imagePullPolicy: Always
livenessProbe:
failureThreshold: 3
@@ -1439,7 +1439,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /var/run/argocd/argocd-cmp-server
image: quay.io/argoproj/argocd:v2.13.0
image: quay.io/argoproj/argocd:v2.13.4
name: copyutil
securityContext:
allowPrivilegeEscalation: false
@@ -1791,7 +1791,7 @@ spec:
key: applicationsetcontroller.enable.scm.providers
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.13.0
image: quay.io/argoproj/argocd:v2.13.4
imagePullPolicy: Always
livenessProbe:
httpGet:
@@ -2117,7 +2117,7 @@ spec:
key: controller.ignore.normalizer.jq.timeout
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.13.0
image: quay.io/argoproj/argocd:v2.13.4
imagePullPolicy: Always
name: argocd-application-controller
ports:

View File

@@ -499,49 +499,49 @@ func init() {
}
var fileDescriptor_eacb9df0ce5738fa = []byte{
// 660 bytes of a gzipped FileDescriptorProto
// 665 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x96, 0x4f, 0x6b, 0xd4, 0x4e,
0x18, 0xc7, 0x99, 0xb6, 0x6c, 0xb7, 0xd3, 0xf2, 0xfb, 0xc1, 0x80, 0xed, 0x1a, 0xeb, 0x5a, 0x72,
0xa8, 0xb5, 0xda, 0x09, 0x5d, 0x3d, 0xe9, 0xc9, 0x3f, 0x50, 0x0a, 0x45, 0x34, 0x2b, 0x0a, 0x7a,
0x90, 0x69, 0xf6, 0x21, 0x8d, 0xcd, 0x26, 0xe3, 0xcc, 0x24, 0x50, 0x8a, 0x17, 0xc1, 0xa3, 0x78,
0x10, 0xdf, 0x80, 0x5e, 0x7c, 0x01, 0xde, 0x3d, 0x78, 0xf1, 0x28, 0xf8, 0x06, 0xa4, 0xf8, 0x0e,
0x7c, 0x03, 0x92, 0x49, 0xf6, 0x4f, 0x86, 0xfd, 0x53, 0x30, 0x7a, 0x9b, 0x67, 0x66, 0xf2, 0xcc,
0x67, 0xbe, 0xcf, 0x93, 0x2f, 0x83, 0x37, 0x25, 0x88, 0x14, 0x84, 0xc3, 0x38, 0x0f, 0x03, 0x8f,
0xa9, 0x20, 0x8e, 0x24, 0x28, 0x23, 0xa4, 0x5c, 0xc4, 0x2a, 0x26, 0xff, 0x95, 0x67, 0xad, 0x55,
0x3f, 0x8e, 0xfd, 0x10, 0x1c, 0xc6, 0x03, 0x87, 0x45, 0x51, 0xac, 0xf2, 0x95, 0x7c, 0xb7, 0xb5,
0xe7, 0x07, 0xea, 0x20, 0xd9, 0xa7, 0x5e, 0xdc, 0x75, 0x98, 0xf0, 0x63, 0x2e, 0xe2, 0x67, 0x7a,
0xb0, 0xe5, 0x75, 0x9c, 0xb4, 0xe5, 0xf0, 0x43, 0x3f, 0xfb, 0x52, 0x0e, 0x9f, 0xe5, 0xa4, 0xdb,
0x2c, 0xe4, 0x07, 0x6c, 0xdb, 0xf1, 0x21, 0x02, 0xc1, 0x14, 0x74, 0xf2, 0x6c, 0xf6, 0x43, 0xbc,
0x7c, 0x73, 0xb0, 0xaf, 0x0d, 0x6a, 0x07, 0xd4, 0xfd, 0x04, 0xc4, 0x11, 0x21, 0x78, 0x2e, 0x62,
0x5d, 0x68, 0xa0, 0x35, 0xb4, 0xb1, 0xe0, 0xea, 0x31, 0xd9, 0xc0, 0xff, 0x33, 0xce, 0x25, 0xa8,
0xbb, 0xac, 0x0b, 0x92, 0x33, 0x0f, 0x1a, 0x33, 0x7a, 0xd9, 0x9c, 0xb6, 0x8f, 0xf1, 0x4a, 0x39,
0xef, 0x5e, 0x20, 0x8b, 0xc4, 0x16, 0xae, 0x67, 0xcc, 0xe0, 0x29, 0xd9, 0x40, 0x6b, 0xb3, 0x1b,
0x0b, 0x6e, 0x3f, 0xce, 0xd6, 0x24, 0x84, 0xe0, 0xa9, 0x58, 0x14, 0x99, 0xfb, 0xf1, 0xa8, 0xc3,
0x67, 0x47, 0x1f, 0xfe, 0x11, 0x99, 0xb7, 0x72, 0x41, 0xf2, 0x4c, 0x5c, 0xd2, 0xc0, 0xf3, 0xc5,
0x61, 0xc5, 0xc5, 0x7a, 0x21, 0x51, 0xd8, 0xa8, 0x83, 0x06, 0x58, 0x6c, 0xed, 0xd1, 0x81, 0xe0,
0xb4, 0x27, 0xb8, 0x1e, 0x3c, 0xf5, 0x3a, 0x34, 0x6d, 0x51, 0x7e, 0xe8, 0xd3, 0x4c, 0x70, 0x3a,
0xf4, 0x39, 0xed, 0x09, 0x4e, 0x0d, 0x0e, 0xe3, 0x0c, 0xfb, 0x0b, 0xc2, 0xe7, 0xca, 0x5b, 0x6e,
0x0b, 0x60, 0x0a, 0x5c, 0x78, 0x9e, 0x80, 0x1c, 0x45, 0x85, 0xfe, 0x3e, 0x15, 0x59, 0xc6, 0xb5,
0x84, 0x4b, 0x10, 0xb9, 0x06, 0x75, 0xb7, 0x88, 0xb2, 0xf9, 0x8e, 0x38, 0x72, 0x93, 0x48, 0x2b,
0x5f, 0x77, 0x8b, 0xc8, 0x7e, 0x62, 0x5e, 0xe2, 0x0e, 0x84, 0x30, 0xb8, 0xc4, 0x9f, 0xb5, 0xd2,
0x23, 0xb3, 0x95, 0x1e, 0x08, 0x80, 0x2a, 0x7a, 0xf4, 0x1d, 0xc2, 0xe7, 0xcd, 0xe6, 0xcf, 0xff,
0x8e, 0xd1, 0xea, 0xb7, 0xff, 0x81, 0xfa, 0x6d, 0x50, 0xf6, 0x1b, 0x84, 0x9b, 0xe3, 0xb8, 0x8a,
0x36, 0xee, 0xe2, 0xa5, 0xe1, 0x92, 0xe9, 0xff, 0x68, 0xb1, 0xb5, 0x5b, 0x19, 0x96, 0x5b, 0x4a,
0xdf, 0xfa, 0x35, 0x8f, 0xcf, 0x94, 0x89, 0xda, 0x20, 0xd2, 0xc0, 0x03, 0xf2, 0x01, 0xe1, 0xd9,
0x1d, 0x50, 0x64, 0x9d, 0x1a, 0xd6, 0x36, 0xda, 0x55, 0xac, 0x4a, 0x95, 0xb3, 0xd7, 0x5f, 0x7e,
0xff, 0xf9, 0x76, 0x66, 0x8d, 0x34, 0xb5, 0x57, 0xa6, 0xdb, 0x86, 0xbf, 0x4a, 0xe7, 0x38, 0x6b,
0x89, 0x17, 0xe4, 0x35, 0xc2, 0xf5, 0x9e, 0x86, 0x64, 0x6b, 0x1a, 0x6a, 0xa9, 0x07, 0x2c, 0x7a,
0xda, 0xed, 0x79, 0x69, 0x6c, 0x5b, 0x33, 0xad, 0xda, 0x2b, 0x63, 0x98, 0xae, 0xa3, 0x4d, 0xf2,
0x1e, 0xe1, 0xb9, 0xcc, 0x10, 0xc9, 0xc5, 0xc9, 0xc9, 0xfb, 0xa6, 0x69, 0xdd, 0xab, 0x52, 0xb7,
0x2c, 0xad, 0x7d, 0x41, 0x73, 0x9e, 0x25, 0xe3, 0x38, 0xc9, 0x27, 0x84, 0x6b, 0xb9, 0x19, 0x91,
0xcb, 0x93, 0x31, 0x4b, 0x96, 0x55, 0x71, 0x89, 0x1d, 0x8d, 0x79, 0x69, 0xbc, 0x9c, 0xa6, 0x77,
0xbd, 0x42, 0xb8, 0x96, 0xdb, 0xcf, 0x34, 0xec, 0x92, 0x49, 0x59, 0x53, 0x3a, 0xb8, 0x5f, 0xdf,
0xa2, 0xe7, 0x36, 0xa7, 0xf5, 0xdc, 0x67, 0x84, 0x97, 0x5c, 0x90, 0x71, 0x22, 0x3c, 0xc8, 0x1c,
0x6b, 0x5a, 0xad, 0xfb, 0xae, 0x56, 0x6d, 0xad, 0xb3, 0xb4, 0xf6, 0x35, 0xcd, 0x4c, 0xc9, 0x95,
0xc9, 0xcc, 0x8e, 0x28, 0x78, 0xb7, 0x94, 0x00, 0xb8, 0xb5, 0xfb, 0xf5, 0xa4, 0x89, 0xbe, 0x9d,
0x34, 0xd1, 0x8f, 0x93, 0x26, 0x7a, 0x7c, 0xe3, 0x74, 0xef, 0x0e, 0x2f, 0x0c, 0x20, 0x32, 0x1f,
0x3a, 0xfb, 0x35, 0xfd, 0xda, 0xb8, 0xfa, 0x3b, 0x00, 0x00, 0xff, 0xff, 0x30, 0x08, 0x85, 0x97,
0x17, 0x09, 0x00, 0x00,
0x18, 0xc7, 0x99, 0xb6, 0x6c, 0xb7, 0xd3, 0xf2, 0xfb, 0xc1, 0x80, 0xed, 0x1a, 0x75, 0x5d, 0x02,
0xd6, 0xda, 0xda, 0x09, 0x5d, 0x3d, 0xd5, 0x93, 0x7f, 0xa0, 0x14, 0x8a, 0x68, 0x56, 0x14, 0xf4,
0x20, 0xd3, 0xec, 0x43, 0x1a, 0x9b, 0x4d, 0xc6, 0x99, 0x49, 0xa0, 0x14, 0x2f, 0x82, 0x67, 0x0f,
0xa2, 0x2f, 0x40, 0x2f, 0xbe, 0x00, 0xef, 0x1e, 0xbc, 0x78, 0x14, 0x7c, 0x03, 0x52, 0x7c, 0x19,
0x1e, 0x24, 0x93, 0xec, 0xb6, 0x19, 0xf6, 0x4f, 0xc1, 0xe8, 0x2d, 0x4f, 0x66, 0xf2, 0x3c, 0x9f,
0xf9, 0x3e, 0x4f, 0xbe, 0x0c, 0x5e, 0x95, 0x20, 0x52, 0x10, 0x0e, 0xe3, 0x3c, 0x0c, 0x3c, 0xa6,
0x82, 0x38, 0x92, 0xa0, 0x8c, 0x90, 0x72, 0x11, 0xab, 0x98, 0xfc, 0x57, 0x7e, 0x6b, 0x9d, 0xf7,
0xe3, 0xd8, 0x0f, 0xc1, 0x61, 0x3c, 0x70, 0x58, 0x14, 0xc5, 0x2a, 0x5f, 0xc9, 0x77, 0x5b, 0x3b,
0x7e, 0xa0, 0xf6, 0x92, 0x5d, 0xea, 0xc5, 0x3d, 0x87, 0x09, 0x3f, 0xe6, 0x22, 0x7e, 0xa6, 0x1f,
0xd6, 0xbd, 0xae, 0x93, 0xb6, 0x1d, 0xbe, 0xef, 0x67, 0x5f, 0xca, 0x93, 0xb5, 0x9c, 0x74, 0x83,
0x85, 0x7c, 0x8f, 0x6d, 0x38, 0x3e, 0x44, 0x20, 0x98, 0x82, 0x6e, 0x9e, 0xcd, 0x7e, 0x88, 0x17,
0x6f, 0x1e, 0xef, 0xeb, 0x80, 0xda, 0x02, 0x75, 0x3f, 0x01, 0x71, 0x40, 0x08, 0x9e, 0x89, 0x58,
0x0f, 0x1a, 0xa8, 0x85, 0x56, 0xe6, 0x5c, 0xfd, 0x4c, 0x56, 0xf0, 0xff, 0x8c, 0x73, 0x09, 0xea,
0x2e, 0xeb, 0x81, 0xe4, 0xcc, 0x83, 0xc6, 0x94, 0x5e, 0x36, 0x5f, 0xdb, 0x87, 0x78, 0xa9, 0x9c,
0x77, 0x27, 0x90, 0x45, 0x62, 0x0b, 0xd7, 0x33, 0x66, 0xf0, 0x94, 0x6c, 0xa0, 0xd6, 0xf4, 0xca,
0x9c, 0x3b, 0x88, 0xb3, 0x35, 0x09, 0x21, 0x78, 0x2a, 0x16, 0x45, 0xe6, 0x41, 0x3c, 0xac, 0xf8,
0xf4, 0xf0, 0xe2, 0x1f, 0x91, 0x79, 0x2a, 0x17, 0x24, 0xcf, 0xc4, 0x25, 0x0d, 0x3c, 0x5b, 0x14,
0x2b, 0x0e, 0xd6, 0x0f, 0x89, 0xc2, 0x46, 0x1f, 0x34, 0xc0, 0x7c, 0x7b, 0x87, 0x1e, 0x0b, 0x4e,
0xfb, 0x82, 0xeb, 0x87, 0xa7, 0x5e, 0x97, 0xa6, 0x6d, 0xca, 0xf7, 0x7d, 0x9a, 0x09, 0x4e, 0x4f,
0x7c, 0x4e, 0xfb, 0x82, 0x53, 0x83, 0xc3, 0xa8, 0x61, 0x7f, 0x41, 0xf8, 0x5c, 0x79, 0xcb, 0x6d,
0x01, 0x4c, 0x81, 0x0b, 0xcf, 0x13, 0x90, 0xc3, 0xa8, 0xd0, 0xdf, 0xa7, 0x22, 0x8b, 0xb8, 0x96,
0x70, 0x09, 0x22, 0xd7, 0xa0, 0xee, 0x16, 0x51, 0xf6, 0xbe, 0x2b, 0x0e, 0xdc, 0x24, 0xd2, 0xca,
0xd7, 0xdd, 0x22, 0xb2, 0x9f, 0x98, 0x87, 0xb8, 0x03, 0x21, 0x1c, 0x1f, 0xe2, 0xcf, 0x46, 0xe9,
0x91, 0x39, 0x4a, 0x0f, 0x04, 0x40, 0x15, 0x33, 0xfa, 0x16, 0xe1, 0x0b, 0xe6, 0xf0, 0xe7, 0x7f,
0xc7, 0x70, 0xf5, 0x3b, 0xff, 0x40, 0xfd, 0x0e, 0x28, 0xfb, 0x35, 0xc2, 0xcd, 0x51, 0x5c, 0xc5,
0x18, 0xf7, 0xf0, 0xc2, 0xc9, 0x96, 0xe9, 0xff, 0x68, 0xbe, 0xbd, 0x5d, 0x19, 0x96, 0x5b, 0x4a,
0xdf, 0xfe, 0x35, 0x8b, 0xcf, 0x94, 0x89, 0x3a, 0x20, 0xd2, 0xc0, 0x03, 0xf2, 0x01, 0xe1, 0xe9,
0x2d, 0x50, 0x64, 0x99, 0x1a, 0xd6, 0x36, 0xdc, 0x55, 0xac, 0x4a, 0x95, 0xb3, 0x97, 0x5f, 0x7e,
0xff, 0xf9, 0x66, 0xaa, 0x45, 0x9a, 0xda, 0x2b, 0xd3, 0x0d, 0xc3, 0x5f, 0xa5, 0x73, 0x98, 0x8d,
0xc4, 0x0b, 0xf2, 0x0e, 0xe1, 0x7a, 0x5f, 0x43, 0xb2, 0x3e, 0x09, 0xb5, 0x34, 0x03, 0x16, 0x3d,
0xed, 0xf6, 0xbc, 0x35, 0xf6, 0x9a, 0x66, 0xba, 0x64, 0xb7, 0x46, 0x31, 0xf5, 0x2d, 0x78, 0x13,
0xad, 0x92, 0xf7, 0x08, 0xcf, 0x64, 0xce, 0x48, 0x2e, 0x8f, 0xaf, 0x32, 0x70, 0x4f, 0xeb, 0x5e,
0x95, 0x02, 0x66, 0x69, 0xed, 0x8b, 0x1a, 0xf8, 0x2c, 0x59, 0x1a, 0x01, 0x4c, 0x3e, 0x21, 0x5c,
0xcb, 0x5d, 0x89, 0xac, 0x8d, 0xc7, 0x2c, 0x79, 0x57, 0xc5, 0xbd, 0x76, 0x34, 0xe6, 0x15, 0x7b,
0x14, 0xe6, 0xa6, 0x69, 0x62, 0xaf, 0x10, 0xae, 0xe5, 0x3e, 0x34, 0x09, 0xbb, 0xe4, 0x56, 0xd6,
0x84, 0x51, 0x1e, 0x34, 0xba, 0x18, 0xbe, 0xd5, 0x49, 0xc3, 0xf7, 0x19, 0xe1, 0x05, 0x17, 0x64,
0x9c, 0x08, 0x0f, 0x32, 0xeb, 0x9a, 0xd4, 0xeb, 0x81, 0xbd, 0x55, 0xdb, 0xeb, 0x2c, 0xad, 0x7d,
0x5d, 0x33, 0x53, 0x72, 0x75, 0x3c, 0xb3, 0x23, 0x0a, 0xde, 0x75, 0x25, 0x00, 0x6e, 0x6d, 0x7f,
0x3d, 0x6a, 0xa2, 0x6f, 0x47, 0x4d, 0xf4, 0xe3, 0xa8, 0x89, 0x1e, 0xdf, 0x38, 0xdd, 0x05, 0xc4,
0x0b, 0x03, 0x88, 0xcc, 0x1b, 0xcf, 0x6e, 0x4d, 0x5f, 0x3b, 0xae, 0xfd, 0x0e, 0x00, 0x00, 0xff,
0xff, 0x05, 0x4d, 0x64, 0x24, 0x20, 0x09, 0x00, 0x00,
}
// Reference imports to suppress errors if they are not otherwise used.

View File

@@ -682,7 +682,7 @@ func RegisterApplicationSetServiceHandlerClient(ctx context.Context, mux *runtim
var (
pattern_ApplicationSetService_Get_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"api", "v1", "applicationsets", "name"}, "", runtime.AssumeColonVerbOpt(true)))
pattern_ApplicationSetService_Generate_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "v1", "applicationsets"}, "", runtime.AssumeColonVerbOpt(true)))
pattern_ApplicationSetService_Generate_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"api", "v1", "applicationsets", "generate"}, "", runtime.AssumeColonVerbOpt(true)))
pattern_ApplicationSetService_List_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "v1", "applicationsets"}, "", runtime.AssumeColonVerbOpt(true)))

View File

@@ -997,6 +997,8 @@ type ApplicationDestination struct {
// nolint:govet
isServerInferred bool `json:"-"`
// nolint:govet
isNameInferred bool `json:"-"`
}
// SetIsServerInferred sets the isServerInferred flag. This is used to allow comparison between two destinations where
@@ -3027,6 +3029,17 @@ func (dest ApplicationDestination) Equals(other ApplicationDestination) bool {
other.Server = ""
other.isServerInferred = false
}
if dest.isNameInferred {
dest.Name = ""
dest.isNameInferred = false
}
if other.isNameInferred {
other.Name = ""
other.isNameInferred = false
}
return reflect.DeepEqual(dest, other)
}
@@ -3261,6 +3274,12 @@ func (d *ApplicationDestination) SetInferredServer(server string) {
d.Server = server
}
// SetInferredName sets the Name field of the destination. See IsNameInferred() for details.
func (d *ApplicationDestination) SetInferredName(name string) {
d.isNameInferred = true
d.Name = name
}
// An ApplicationDestination has an 'inferred server' if the ApplicationDestination
// contains a Name, but not a Server URL. In this case it is necessary to retrieve
// the Server URL by looking up the cluster name.
@@ -3271,6 +3290,10 @@ func (d *ApplicationDestination) IsServerInferred() bool {
return d.isServerInferred
}
func (d *ApplicationDestination) IsNameInferred() bool {
return d.isNameInferred
}
// MarshalJSON marshals an application destination to JSON format
func (d *ApplicationDestination) MarshalJSON() ([]byte, error) {
type Alias ApplicationDestination
@@ -3279,6 +3302,11 @@ func (d *ApplicationDestination) MarshalJSON() ([]byte, error) {
dest = dest.DeepCopy()
dest.Server = ""
}
if d.isNameInferred {
dest = dest.DeepCopy()
dest.Name = ""
}
return json.Marshal(&struct{ *Alias }{Alias: (*Alias)(dest)})
}

View File

@@ -1,9 +1,24 @@
hs = {}
if obj.status == nil or obj.status.compliant == nil then
if obj.status == nil then
hs.status = "Progressing"
hs.message = "Waiting for the status to be reported"
return hs
end
-- A policy will not have a compliant field but will have a placement key set if
-- it is not being applied to any clusters
if obj.status.compliant == nil and #obj.status.placement > 0 and obj.status.status == nil then
hs.status = "Healthy"
hs.message = "No clusters match this policy"
return hs
end
if obj.status.compliant == nil then
hs.status = "Progressing"
hs.message = "Waiting for the status to be reported"
return hs
end
if obj.status.compliant == "Compliant" then
hs.status = "Healthy"
else

View File

@@ -15,3 +15,11 @@ tests:
status: Healthy
message: All templates are compliant
inputPath: testdata/healthy_replicated.yaml
- healthStatus:
status: Progressing
message: Waiting for the status to be reported
inputPath: testdata/progressing_no_status.yaml
- healthStatus:
status: Healthy
message: No clusters match this policy
inputPath: testdata/healthy_with_placement_empty_compliant.yaml

View File

@@ -0,0 +1,55 @@
apiVersion: policy.open-cluster-management.io/v1
kind: Policy
metadata:
annotations:
argocd.argoproj.io/compare-options: IgnoreExtraneous
argocd.argoproj.io/sync-options: SkipDryRunOnMissingResource=true
labels:
argocd.argoproj.io/instance: acm
name: acm-hub-ca-policy
namespace: open-cluster-management
spec:
disabled: false
policy-templates:
- objectDefinition:
apiVersion: policy.open-cluster-management.io/v1
kind: ConfigurationPolicy
metadata:
name: acm-hub-ca-config-policy
spec:
namespaceSelector:
include:
- default
object-templates:
- complianceType: mustonlyhave
objectDefinition:
apiVersion: v1
data:
hub-kube-root-ca.crt: '{{hub fromConfigMap "" "kube-root-ca.crt" "ca.crt"
| base64enc hub}}'
hub-openshift-service-ca.crt: '{{hub fromConfigMap "" "openshift-service-ca.crt"
"service-ca.crt" | base64enc hub}}'
kind: Secret
metadata:
name: hub-ca
namespace: golang-external-secrets
type: Opaque
- complianceType: mustonlyhave
objectDefinition:
apiVersion: v1
data:
hub-kube-root-ca.crt: |
{{hub fromConfigMap "" "kube-root-ca.crt" "ca.crt" | autoindent hub}}
hub-openshift-service-ca.crt: |
{{hub fromConfigMap "" "openshift-service-ca.crt" "service-ca.crt" | autoindent hub}}
kind: ConfigMap
metadata:
name: trusted-hub-bundle
namespace: imperative
remediationAction: enforce
severity: medium
remediationAction: enforce
status:
placement:
- placementBinding: acm-hub-ca-policy-placement-binding
placementRule: acm-hub-ca-policy-placement

View File

@@ -0,0 +1,51 @@
apiVersion: policy.open-cluster-management.io/v1
kind: Policy
metadata:
annotations:
argocd.argoproj.io/compare-options: IgnoreExtraneous
argocd.argoproj.io/sync-options: SkipDryRunOnMissingResource=true
labels:
argocd.argoproj.io/instance: acm
name: acm-hub-ca-policy
namespace: open-cluster-management
spec:
disabled: false
policy-templates:
- objectDefinition:
apiVersion: policy.open-cluster-management.io/v1
kind: ConfigurationPolicy
metadata:
name: acm-hub-ca-config-policy
spec:
namespaceSelector:
include:
- default
object-templates:
- complianceType: mustonlyhave
objectDefinition:
apiVersion: v1
data:
hub-kube-root-ca.crt: '{{hub fromConfigMap "" "kube-root-ca.crt" "ca.crt"
| base64enc hub}}'
hub-openshift-service-ca.crt: '{{hub fromConfigMap "" "openshift-service-ca.crt"
"service-ca.crt" | base64enc hub}}'
kind: Secret
metadata:
name: hub-ca
namespace: golang-external-secrets
type: Opaque
- complianceType: mustonlyhave
objectDefinition:
apiVersion: v1
data:
hub-kube-root-ca.crt: |
{{hub fromConfigMap "" "kube-root-ca.crt" "ca.crt" | autoindent hub}}
hub-openshift-service-ca.crt: |
{{hub fromConfigMap "" "openshift-service-ca.crt" "service-ca.crt" | autoindent hub}}
kind: ConfigMap
metadata:
name: trusted-hub-bundle
namespace: imperative
remediationAction: enforce
severity: medium
remediationAction: enforce

View File

@@ -7,12 +7,13 @@ hs.message = "Waiting for status"
if obj.status ~= nil then
if obj.status.conditions ~= nil then
for i, condition in ipairs(obj.status.conditions) do
if condition.status == "False" then
-- InsufficientPods can have valid use cases
-- See a discussion in https://github.com/argoproj/argo-cd/issues/20171 for more details
if condition.status == "False" and condition.reason ~= "InsufficientPods" then
hs.status = "Degraded"
hs.message = "PodDisruptionBudget has " .. condition.reason
return hs
end
if condition.status == "True" then
else
hs.status = "Healthy"
hs.message = "PodDisruptionBudget has " .. condition.reason
end

View File

@@ -9,5 +9,5 @@ tests:
inputPath: testdata/progressing.yaml
- healthStatus:
status: Degraded
message: 'PodDisruptionBudget has InsufficientPods'
message: 'PodDisruptionBudget has SyncFailed'
inputPath: testdata/degraded.yaml

View File

@@ -16,6 +16,12 @@ status:
reason: InsufficientPods
status: "False"
type: DisruptionAllowed
- lastTransitionTime: "2024-09-06T18:29:06Z"
message: ""
observedGeneration: 2
reason: SyncFailed
status: "False"
type: DisruptionAllowed
currentHealthy: 2
desiredHealthy: 3
disruptionsAllowed: 0

View File

@@ -112,6 +112,7 @@ func NewServer(
settingsMgr *settings.SettingsManager,
projInformer cache.SharedIndexInformer,
enabledNamespaces []string,
enableK8sEvent []string,
) (application.ApplicationServiceServer, AppResourceTreeFn) {
if appBroadcaster == nil {
appBroadcaster = &broadcasterHandler{}
@@ -133,7 +134,7 @@ func NewServer(
kubectl: kubectl,
enf: enf,
projectLock: projectLock,
auditLogger: argo.NewAuditLogger(namespace, kubeclientset, "argocd-server"),
auditLogger: argo.NewAuditLogger(namespace, kubeclientset, "argocd-server", enableK8sEvent),
settingsMgr: settingsMgr,
projInformer: projInformer,
enabledNamespaces: enabledNamespaces,
@@ -368,7 +369,13 @@ func (s *Server) Create(ctx context.Context, q *application.ApplicationCreateReq
if err != nil {
return nil, status.Errorf(codes.Internal, "unable to check existing application details (%s): %v", appNs, err)
}
equalSpecs := reflect.DeepEqual(existing.Spec, a.Spec) &&
if err := argo.ValidateDestination(ctx, &existing.Spec.Destination, s.db); err != nil {
return nil, status.Errorf(codes.InvalidArgument, "application destination spec for %s is invalid: %s", existing.Name, err.Error())
}
equalSpecs := existing.Spec.Destination.Equals(a.Spec.Destination) &&
reflect.DeepEqual(existing.Spec, a.Spec) &&
reflect.DeepEqual(existing.Labels, a.Labels) &&
reflect.DeepEqual(existing.Annotations, a.Annotations) &&
reflect.DeepEqual(existing.Finalizers, a.Finalizers)
@@ -2210,7 +2217,7 @@ func getAmbiguousRevision(app *appv1.Application, syncReq *application.Applicati
ambiguousRevision := ""
if app.Spec.HasMultipleSources() {
for i, pos := range syncReq.SourcePositions {
if pos == int64(sourceIndex) {
if pos == int64(sourceIndex+1) {
ambiguousRevision = syncReq.Revisions[i]
}
}

View File

@@ -69,6 +69,8 @@ const (
fakeRepoURL = "https://git.com/repo.git"
)
var testEnableEventList []string = argo.DefaultEnableEventList()
func fakeRepo() *appsv1.Repository {
return &appsv1.Repository{
Repo: fakeRepoURL,
@@ -306,6 +308,7 @@ func newTestAppServerWithEnforcerConfigure(f func(*rbac.Enforcer), t *testing.T,
settingsMgr,
projInformer,
[]string{},
testEnableEventList,
)
return server.(*Server)
}
@@ -486,6 +489,7 @@ func newTestAppServerWithEnforcerConfigureWithBenchmark(f func(*rbac.Enforcer),
settingsMgr,
projInformer,
[]string{},
testEnableEventList,
)
return server.(*Server)
}
@@ -2934,7 +2938,7 @@ func TestGetAmbiguousRevision_MultiSource(t *testing.T) {
},
}
syncReq := &application.ApplicationSyncRequest{
SourcePositions: []int64{0, 1},
SourcePositions: []int64{1, 2},
Revisions: []string{"rev1", "rev2"},
}

View File

@@ -120,16 +120,22 @@ func mergeLogStreams(streams []chan logEntry, bufferingDuration time.Duration) c
var sentAt time.Time
ticker := time.NewTicker(bufferingDuration)
done := make(chan struct{})
go func() {
for range ticker.C {
sentAtLock.Lock()
// waited long enough for logs from each streams, send everything accumulated
if sentAt.Add(bufferingDuration).Before(time.Now()) {
_ = send(true)
sentAt = time.Now()
}
for {
select {
case <-done:
return
case <-ticker.C:
sentAtLock.Lock()
// waited long enough for logs from each streams, send everything accumulated
if sentAt.Add(bufferingDuration).Before(time.Now()) {
_ = send(true)
sentAt = time.Now()
}
sentAtLock.Unlock()
sentAtLock.Unlock()
}
}
}()
@@ -145,6 +151,11 @@ func mergeLogStreams(streams []chan logEntry, bufferingDuration time.Duration) c
_ = send(true)
ticker.Stop()
// ticker.Stop() does not close the channel, and it does not wait for the channel to be drained. So we need to
// explicitly prevent the gorountine from leaking by closing the channel. We also need to prevent the goroutine
// from calling `send` again, because `send` pushes to the `merged` channel which we're about to close.
// This describes the approach nicely: https://stackoverflow.com/questions/17797754/ticker-stop-behaviour-in-golang
done <- struct{}{}
close(merged)
}()
return merged

View File

@@ -75,3 +75,33 @@ func TestMergeLogStreams(t *testing.T) {
assert.Equal(t, []string{"1", "2", "3", "4"}, lines)
}
func TestMergeLogStreams_RaceCondition(t *testing.T) {
// Test for regression of this issue: https://github.com/argoproj/argo-cd/issues/7006
for i := 0; i < 5000; i++ {
first := make(chan logEntry)
second := make(chan logEntry)
go func() {
parseLogsStream("first", io.NopCloser(strings.NewReader(`2021-02-09T00:00:01Z 1`)), first)
time.Sleep(time.Duration(i%3) * time.Millisecond)
close(first)
}()
go func() {
parseLogsStream("second", io.NopCloser(strings.NewReader(`2021-02-09T00:00:02Z 2`)), second)
time.Sleep(time.Duration((i+1)%3) * time.Millisecond)
close(second)
}()
merged := mergeLogStreams([]chan logEntry{first, second}, 1*time.Millisecond)
// Drain the channel
for range merged {
}
// This test intentionally doesn't test the order of the output. Under these intense conditions, the test would
// fail often due to out of order entries. This test is only meant to reproduce a race between a channel writer
// and channel closer.
}
}

View File

@@ -88,6 +88,7 @@ func NewServer(
scmRootCAPath string,
allowedScmProviders []string,
enableScmProviders bool,
enableK8sEvent []string,
) applicationset.ApplicationSetServiceServer {
s := &Server{
ns: namespace,
@@ -103,7 +104,7 @@ func NewServer(
projLister: projLister,
settings: settings,
projectLock: projectLock,
auditLogger: argo.NewAuditLogger(namespace, kubeclientset, "argocd-server"),
auditLogger: argo.NewAuditLogger(namespace, kubeclientset, "argocd-server", enableK8sEvent),
enabledNamespaces: enabledNamespaces,
GitSubmoduleEnabled: gitSubmoduleEnabled,
EnableNewGitFileGlobbing: enableNewGitFileGlobbing,

View File

@@ -74,7 +74,7 @@ service ApplicationSetService {
// Generate generates
rpc Generate (ApplicationSetGenerateRequest) returns (ApplicationSetGenerateResponse) {
option (google.api.http) = {
post: "/api/v1/applicationsets"
post: "/api/v1/applicationsets/generate"
body: "*"
};
}

View File

@@ -22,6 +22,7 @@ import (
apps "github.com/argoproj/argo-cd/v2/pkg/client/clientset/versioned/fake"
appinformer "github.com/argoproj/argo-cd/v2/pkg/client/informers/externalversions"
"github.com/argoproj/argo-cd/v2/server/rbacpolicy"
"github.com/argoproj/argo-cd/v2/util/argo"
"github.com/argoproj/argo-cd/v2/util/assets"
"github.com/argoproj/argo-cd/v2/util/db"
"github.com/argoproj/argo-cd/v2/util/errors"
@@ -34,6 +35,8 @@ const (
fakeRepoURL = "https://git.com/repo.git"
)
var testEnableEventList []string = argo.DefaultEnableEventList()
func fakeRepo() *appsv1.Repository {
return &appsv1.Repository{
Repo: fakeRepoURL,
@@ -162,6 +165,7 @@ func newTestAppSetServerWithEnforcerConfigure(f func(*rbac.Enforcer), namespace
"",
[]string{},
true,
testEnableEventList,
)
return server.(*Server)
}

View File

@@ -58,9 +58,9 @@ type Server struct {
// NewServer returns a new instance of the Project service
func NewServer(ns string, kubeclientset kubernetes.Interface, appclientset appclientset.Interface, enf *rbac.Enforcer, projectLock sync.KeyLock, sessionMgr *session.SessionManager, policyEnf *rbacpolicy.RBACPolicyEnforcer,
projInformer cache.SharedIndexInformer, settingsMgr *settings.SettingsManager, db db.ArgoDB,
projInformer cache.SharedIndexInformer, settingsMgr *settings.SettingsManager, db db.ArgoDB, enableK8sEvent []string,
) *Server {
auditLogger := argo.NewAuditLogger(ns, kubeclientset, "argocd-server")
auditLogger := argo.NewAuditLogger(ns, kubeclientset, "argocd-server", enableK8sEvent)
return &Server{
enf: enf, policyEnf: policyEnf, appclientset: appclientset, kubeclientset: kubeclientset, ns: ns, projectLock: projectLock, auditLogger: auditLogger, sessionMgr: sessionMgr,
projInformer: projInformer, settingsMgr: settingsMgr, db: db,

View File

@@ -6,6 +6,7 @@ import (
"strings"
"testing"
"github.com/argoproj/argo-cd/v2/util/argo"
"github.com/argoproj/argo-cd/v2/util/db"
"github.com/argoproj/pkg/sync"
@@ -37,6 +38,8 @@ import (
const testNamespace = "default"
var testEnableEventList []string = argo.DefaultEnableEventList()
func TestProjectServer(t *testing.T) {
kubeclientset := fake.NewSimpleClientset(&corev1.ConfigMap{
ObjectMeta: v1.ObjectMeta{
@@ -91,7 +94,7 @@ func TestProjectServer(t *testing.T) {
role1 := v1alpha1.ProjectRole{Name: roleName, JWTTokens: []v1alpha1.JWTToken{{IssuedAt: 1}}}
projectWithRole.Spec.Roles = append(projectWithRole.Spec.Roles, role1)
argoDB := db.NewDB("default", settingsMgr, kubeclientset)
projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projectWithRole), enforcer, sync.NewKeyLock(), sessionMgr, nil, projInformer, settingsMgr, argoDB)
projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projectWithRole), enforcer, sync.NewKeyLock(), sessionMgr, nil, projInformer, settingsMgr, argoDB, testEnableEventList)
err := projectServer.NormalizeProjs()
require.NoError(t, err)
@@ -105,7 +108,7 @@ func TestProjectServer(t *testing.T) {
enforcer.SetDefaultRole("role:projects")
_ = enforcer.SetBuiltinPolicy("p, role:projects, projects, update, *, allow")
argoDB := db.NewDB("default", settingsMgr, kubeclientset)
projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(&existingProj, &existingApp), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB)
projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(&existingProj, &existingApp), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB, testEnableEventList)
updatedProj := existingProj.DeepCopy()
updatedProj.Spec.Destinations = nil
@@ -119,7 +122,7 @@ func TestProjectServer(t *testing.T) {
enforcer.SetDefaultRole("role:projects")
_ = enforcer.SetBuiltinPolicy("p, role:projects, projects, update, *, allow")
argoDB := db.NewDB("default", settingsMgr, kubeclientset)
projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(&existingProj, &existingApp), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB)
projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(&existingProj, &existingApp), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB, testEnableEventList)
updatedProj := existingProj.DeepCopy()
updatedProj.Spec.SourceRepos = nil
@@ -133,7 +136,7 @@ func TestProjectServer(t *testing.T) {
enforcer.SetDefaultRole("role:projects")
_ = enforcer.SetBuiltinPolicy("p, role:projects, projects, update, *, allow")
argoDB := db.NewDB("default", settingsMgr, kubeclientset)
projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(&existingProj, &existingApp), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB)
projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(&existingProj, &existingApp), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB, testEnableEventList)
updatedProj := existingProj.DeepCopy()
updatedProj.Spec.ClusterResourceWhitelist = []metav1.GroupKind{{}}
@@ -147,7 +150,7 @@ func TestProjectServer(t *testing.T) {
enforcer.SetDefaultRole("role:projects")
_ = enforcer.SetBuiltinPolicy("p, role:projects, projects, update, *, allow")
argoDB := db.NewDB("default", settingsMgr, kubeclientset)
projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(&existingProj, &existingApp), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB)
projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(&existingProj, &existingApp), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB, testEnableEventList)
updatedProj := existingProj.DeepCopy()
updatedProj.Spec.NamespaceResourceBlacklist = []metav1.GroupKind{{}}
@@ -166,7 +169,7 @@ func TestProjectServer(t *testing.T) {
}
argoDB := db.NewDB("default", settingsMgr, kubeclientset)
projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(&existingProj, &existingApp), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB)
projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(&existingProj, &existingApp), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB, testEnableEventList)
updatedProj := existingProj.DeepCopy()
updatedProj.Spec.Destinations = updatedProj.Spec.Destinations[1:]
@@ -183,7 +186,7 @@ func TestProjectServer(t *testing.T) {
}
argoDB := db.NewDB("default", settingsMgr, kubeclientset)
projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(&existingProj, &existingApp), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB)
projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(&existingProj, &existingApp), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB, testEnableEventList)
updatedProj := existingProj.DeepCopy()
updatedProj.Spec.Destinations = updatedProj.Spec.Destinations[1:]
@@ -202,7 +205,7 @@ func TestProjectServer(t *testing.T) {
}
argoDB := db.NewDB("default", settingsMgr, kubeclientset)
projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(&existingProj, &existingApp), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB)
projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(&existingProj, &existingApp), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB, testEnableEventList)
updatedProj := existingProj.DeepCopy()
updatedProj.Spec.SourceRepos = []string{}
@@ -219,7 +222,7 @@ func TestProjectServer(t *testing.T) {
}
argoDB := db.NewDB("default", settingsMgr, kubeclientset)
projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(&existingProj, &existingApp), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB)
projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(&existingProj, &existingApp), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB, testEnableEventList)
updatedProj := existingProj.DeepCopy()
updatedProj.Spec.SourceRepos = []string{}
@@ -239,7 +242,7 @@ func TestProjectServer(t *testing.T) {
Spec: v1alpha1.ApplicationSpec{Project: "test", Source: &v1alpha1.ApplicationSource{RepoURL: "https://github.com/argoproj/argo-cd.git"}},
}
argoDB := db.NewDB("default", settingsMgr, kubeclientset)
projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(proj, &existingApp), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB)
projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(proj, &existingApp), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB, testEnableEventList)
updatedProj := proj.DeepCopy()
updatedProj.Spec.SourceRepos = []string{"https://github.com/argoproj/*"}
@@ -266,7 +269,7 @@ func TestProjectServer(t *testing.T) {
argoDB := db.NewDB("default", settingsMgr, kubeclientset)
projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(proj, &existingApp), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB)
projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(proj, &existingApp), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB, testEnableEventList)
updatedProj := proj.DeepCopy()
updatedProj.Spec.Destinations = []v1alpha1.ApplicationDestination{
@@ -281,7 +284,7 @@ func TestProjectServer(t *testing.T) {
t.Run("TestDeleteProjectSuccessful", func(t *testing.T) {
argoDB := db.NewDB("default", settingsMgr, kubeclientset)
projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(&existingProj), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB)
projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(&existingProj), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB, testEnableEventList)
_, err := projectServer.Delete(context.Background(), &project.ProjectQuery{Name: "test"})
@@ -294,7 +297,7 @@ func TestProjectServer(t *testing.T) {
Spec: v1alpha1.AppProjectSpec{},
}
argoDB := db.NewDB("default", settingsMgr, kubeclientset)
projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(&defaultProj), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB)
projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(&defaultProj), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB, testEnableEventList)
_, err := projectServer.Delete(context.Background(), &project.ProjectQuery{Name: defaultProj.Name})
statusCode, _ := status.FromError(err)
@@ -308,7 +311,7 @@ func TestProjectServer(t *testing.T) {
}
argoDB := db.NewDB("default", settingsMgr, kubeclientset)
projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(&existingProj, &existingApp), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB)
projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(&existingProj, &existingApp), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB, testEnableEventList)
_, err := projectServer.Delete(context.Background(), &project.ProjectQuery{Name: "test"})
@@ -335,7 +338,7 @@ func TestProjectServer(t *testing.T) {
projectWithRole.Spec.Roles = []v1alpha1.ProjectRole{{Name: tokenName}}
argoDB := db.NewDB("default", settingsMgr, kubeclientset)
projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projectWithRole), enforcer, sync.NewKeyLock(), sessionMgr, policyEnf, projInformer, settingsMgr, argoDB)
projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projectWithRole), enforcer, sync.NewKeyLock(), sessionMgr, policyEnf, projInformer, settingsMgr, argoDB, testEnableEventList)
_, err := projectServer.CreateToken(ctx, &project.ProjectTokenCreateRequest{Project: projectWithRole.Name, Role: tokenName, ExpiresIn: 1})
assert.EqualError(t, err, "rpc error: code = PermissionDenied desc = permission denied: projects, update, test")
})
@@ -345,7 +348,7 @@ func TestProjectServer(t *testing.T) {
projectWithRole := existingProj.DeepCopy()
projectWithRole.Spec.Roles = []v1alpha1.ProjectRole{{Name: tokenName, Groups: []string{"my-group"}}}
argoDB := db.NewDB("default", settingsMgr, kubeclientset)
projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projectWithRole), enforcer, sync.NewKeyLock(), sessionMgr, policyEnf, projInformer, settingsMgr, argoDB)
projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projectWithRole), enforcer, sync.NewKeyLock(), sessionMgr, policyEnf, projInformer, settingsMgr, argoDB, testEnableEventList)
_, err := projectServer.CreateToken(ctx, &project.ProjectTokenCreateRequest{Project: projectWithRole.Name, Role: tokenName, ExpiresIn: 1})
require.NoError(t, err)
})
@@ -359,7 +362,7 @@ func TestProjectServer(t *testing.T) {
sessionMgr := session.NewSessionManager(settingsMgr, test.NewFakeProjListerFromInterface(clientset.ArgoprojV1alpha1().AppProjects("default")), "", nil, session.NewUserStateStorage(nil))
argoDB := db.NewDB("default", settingsMgr, kubeclientset)
projectServer := NewServer("default", fake.NewSimpleClientset(), clientset, enforcer, sync.NewKeyLock(), sessionMgr, policyEnf, projInformer, settingsMgr, argoDB)
projectServer := NewServer("default", fake.NewSimpleClientset(), clientset, enforcer, sync.NewKeyLock(), sessionMgr, policyEnf, projInformer, settingsMgr, argoDB, testEnableEventList)
tokenResponse, err := projectServer.CreateToken(context.Background(), &project.ProjectTokenCreateRequest{Project: projectWithRole.Name, Role: tokenName, ExpiresIn: 100})
require.NoError(t, err)
claims, _, err := sessionMgr.Parse(tokenResponse.Token)
@@ -380,7 +383,7 @@ func TestProjectServer(t *testing.T) {
sessionMgr := session.NewSessionManager(settingsMgr, test.NewFakeProjListerFromInterface(clientset.ArgoprojV1alpha1().AppProjects("default")), "", nil, session.NewUserStateStorage(nil))
argoDB := db.NewDB("default", settingsMgr, kubeclientset)
projectServer := NewServer("default", fake.NewSimpleClientset(), clientset, enforcer, sync.NewKeyLock(), sessionMgr, policyEnf, projInformer, settingsMgr, argoDB)
projectServer := NewServer("default", fake.NewSimpleClientset(), clientset, enforcer, sync.NewKeyLock(), sessionMgr, policyEnf, projInformer, settingsMgr, argoDB, testEnableEventList)
tokenResponse, err := projectServer.CreateToken(context.Background(), &project.ProjectTokenCreateRequest{Project: projectWithRole.Name, Role: tokenName, ExpiresIn: 1, Id: id})
require.NoError(t, err)
claims, _, err := sessionMgr.Parse(tokenResponse.Token)
@@ -401,7 +404,7 @@ func TestProjectServer(t *testing.T) {
sessionMgr := session.NewSessionManager(settingsMgr, test.NewFakeProjListerFromInterface(clientset.ArgoprojV1alpha1().AppProjects("default")), "", nil, session.NewUserStateStorage(nil))
argoDB := db.NewDB("default", settingsMgr, kubeclientset)
projectServer := NewServer("default", fake.NewSimpleClientset(), clientset, enforcer, sync.NewKeyLock(), sessionMgr, policyEnf, projInformer, settingsMgr, argoDB)
projectServer := NewServer("default", fake.NewSimpleClientset(), clientset, enforcer, sync.NewKeyLock(), sessionMgr, policyEnf, projInformer, settingsMgr, argoDB, testEnableEventList)
tokenResponse, err := projectServer.CreateToken(context.Background(), &project.ProjectTokenCreateRequest{Project: projectWithRole.Name, Role: tokenName, ExpiresIn: 1, Id: id})
require.NoError(t, err)
@@ -430,7 +433,7 @@ func TestProjectServer(t *testing.T) {
token := v1alpha1.ProjectRole{Name: tokenName, JWTTokens: []v1alpha1.JWTToken{{IssuedAt: issuedAt}, {IssuedAt: secondIssuedAt}}}
projWithToken.Spec.Roles = append(projWithToken.Spec.Roles, token)
argoDB := db.NewDB("default", settingsMgr, kubeclientset)
projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projWithToken), enforcer, sync.NewKeyLock(), sessionMgr, policyEnf, projInformer, settingsMgr, argoDB)
projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projWithToken), enforcer, sync.NewKeyLock(), sessionMgr, policyEnf, projInformer, settingsMgr, argoDB, testEnableEventList)
_, err := projectServer.DeleteToken(ctx, &project.ProjectTokenDeleteRequest{Project: projWithToken.Name, Role: tokenName, Iat: issuedAt})
assert.EqualError(t, err, "rpc error: code = PermissionDenied desc = permission denied: projects, update, test")
})
@@ -443,7 +446,7 @@ func TestProjectServer(t *testing.T) {
token := v1alpha1.ProjectRole{Name: tokenName, Groups: []string{"my-group"}, JWTTokens: []v1alpha1.JWTToken{{IssuedAt: issuedAt}, {IssuedAt: secondIssuedAt}}}
projWithToken.Spec.Roles = append(projWithToken.Spec.Roles, token)
argoDB := db.NewDB("default", settingsMgr, kubeclientset)
projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projWithToken), enforcer, sync.NewKeyLock(), sessionMgr, policyEnf, projInformer, settingsMgr, argoDB)
projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projWithToken), enforcer, sync.NewKeyLock(), sessionMgr, policyEnf, projInformer, settingsMgr, argoDB, testEnableEventList)
_, err := projectServer.DeleteToken(ctx, &project.ProjectTokenDeleteRequest{Project: projWithToken.Name, Role: tokenName, Iat: issuedAt})
require.NoError(t, err)
})
@@ -459,7 +462,7 @@ p, role:admin, projects, update, *, allow`)
token := v1alpha1.ProjectRole{Name: tokenName, JWTTokens: []v1alpha1.JWTToken{{IssuedAt: issuedAt}, {IssuedAt: secondIssuedAt}}}
projWithToken.Spec.Roles = append(projWithToken.Spec.Roles, token)
argoDB := db.NewDB("default", settingsMgr, kubeclientset)
projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projWithToken), enforcer, sync.NewKeyLock(), sessionMgr, policyEnf, projInformer, settingsMgr, argoDB)
projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projWithToken), enforcer, sync.NewKeyLock(), sessionMgr, policyEnf, projInformer, settingsMgr, argoDB, testEnableEventList)
_, err := projectServer.DeleteToken(ctx, &project.ProjectTokenDeleteRequest{Project: projWithToken.Name, Role: tokenName, Iat: issuedAt})
require.NoError(t, err)
projWithoutToken, err := projectServer.Get(context.Background(), &project.ProjectQuery{Name: projWithToken.Name})
@@ -483,7 +486,7 @@ p, role:admin, projects, update, *, allow`)
token := v1alpha1.ProjectRole{Name: tokenName, JWTTokens: []v1alpha1.JWTToken{{IssuedAt: issuedAt, ID: id}, {IssuedAt: secondIssuedAt, ID: secondId}}}
projWithToken.Spec.Roles = append(projWithToken.Spec.Roles, token)
argoDB := db.NewDB("default", settingsMgr, kubeclientset)
projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projWithToken), enforcer, sync.NewKeyLock(), sessionMgr, policyEnf, projInformer, settingsMgr, argoDB)
projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projWithToken), enforcer, sync.NewKeyLock(), sessionMgr, policyEnf, projInformer, settingsMgr, argoDB, testEnableEventList)
_, err := projectServer.DeleteToken(ctx, &project.ProjectTokenDeleteRequest{Project: projWithToken.Name, Role: tokenName, Iat: secondIssuedAt, Id: id})
require.NoError(t, err)
projWithoutToken, err := projectServer.Get(context.Background(), &project.ProjectQuery{Name: projWithToken.Name})
@@ -502,7 +505,7 @@ p, role:admin, projects, update, *, allow`)
token := v1alpha1.ProjectRole{Name: tokenName, JWTTokens: []v1alpha1.JWTToken{{IssuedAt: 1}}}
projWithToken.Spec.Roles = append(projWithToken.Spec.Roles, token)
argoDB := db.NewDB("default", settingsMgr, kubeclientset)
projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projWithToken), enforcer, sync.NewKeyLock(), sessionMgr, policyEnf, projInformer, settingsMgr, argoDB)
projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projWithToken), enforcer, sync.NewKeyLock(), sessionMgr, policyEnf, projInformer, settingsMgr, argoDB, testEnableEventList)
_, err := projectServer.CreateToken(context.Background(), &project.ProjectTokenCreateRequest{Project: projWithToken.Name, Role: tokenName})
require.NoError(t, err)
projWithTwoTokens, err := projectServer.Get(context.Background(), &project.ProjectQuery{Name: projWithToken.Name})
@@ -516,7 +519,7 @@ p, role:admin, projects, update, *, allow`)
wildSourceRepo := "*"
proj.Spec.SourceRepos = append(proj.Spec.SourceRepos, wildSourceRepo)
argoDB := db.NewDB("default", settingsMgr, kubeclientset)
projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(proj), enforcer, sync.NewKeyLock(), nil, policyEnf, projInformer, settingsMgr, argoDB)
projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(proj), enforcer, sync.NewKeyLock(), nil, policyEnf, projInformer, settingsMgr, argoDB, testEnableEventList)
request := &project.ProjectUpdateRequest{Project: proj}
updatedProj, err := projectServer.Update(context.Background(), request)
require.NoError(t, err)
@@ -535,7 +538,7 @@ p, role:admin, projects, update, *, allow`)
role.Policies = append(role.Policies, policy)
projWithRole.Spec.Roles = append(projWithRole.Spec.Roles, role)
argoDB := db.NewDB("default", settingsMgr, kubeclientset)
projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projWithRole), enforcer, sync.NewKeyLock(), nil, policyEnf, projInformer, settingsMgr, argoDB)
projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projWithRole), enforcer, sync.NewKeyLock(), nil, policyEnf, projInformer, settingsMgr, argoDB, testEnableEventList)
request := &project.ProjectUpdateRequest{Project: projWithRole}
_, err := projectServer.Update(context.Background(), request)
require.NoError(t, err)
@@ -557,7 +560,7 @@ p, role:admin, projects, update, *, allow`)
role.Policies = append(role.Policies, policy)
projWithRole.Spec.Roles = append(projWithRole.Spec.Roles, role)
argoDB := db.NewDB("default", settingsMgr, kubeclientset)
projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projWithRole), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB)
projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projWithRole), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB, testEnableEventList)
request := &project.ProjectUpdateRequest{Project: projWithRole}
_, err := projectServer.Update(context.Background(), request)
expectedErr := fmt.Sprintf("rpc error: code = AlreadyExists desc = policy '%s' already exists for role '%s'", policy, roleName)
@@ -577,7 +580,7 @@ p, role:admin, projects, update, *, allow`)
role.Policies = append(role.Policies, policy)
projWithRole.Spec.Roles = append(projWithRole.Spec.Roles, role)
argoDB := db.NewDB("default", settingsMgr, kubeclientset)
projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projWithRole), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB)
projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projWithRole), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB, testEnableEventList)
request := &project.ProjectUpdateRequest{Project: projWithRole}
_, err := projectServer.Update(context.Background(), request)
assert.Contains(t, err.Error(), "object must be of form 'test/*', 'test[/<NAMESPACE>]/<APPNAME>' or 'test/<APPNAME>'")
@@ -596,7 +599,7 @@ p, role:admin, projects, update, *, allow`)
role.Policies = append(role.Policies, invalidPolicy)
projWithRole.Spec.Roles = append(projWithRole.Spec.Roles, role)
argoDB := db.NewDB("default", settingsMgr, kubeclientset)
projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projWithRole), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB)
projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projWithRole), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB, testEnableEventList)
request := &project.ProjectUpdateRequest{Project: projWithRole}
_, err := projectServer.Update(context.Background(), request)
assert.Contains(t, err.Error(), "policy subject must be: 'proj:test:testRole'")
@@ -615,7 +618,7 @@ p, role:admin, projects, update, *, allow`)
role.Policies = append(role.Policies, invalidPolicy)
projWithRole.Spec.Roles = append(projWithRole.Spec.Roles, role)
argoDB := db.NewDB("default", settingsMgr, kubeclientset)
projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projWithRole), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB)
projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projWithRole), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB, testEnableEventList)
request := &project.ProjectUpdateRequest{Project: projWithRole}
_, err := projectServer.Update(context.Background(), request)
assert.Contains(t, err.Error(), "policy subject must be: 'proj:test:testRole'")
@@ -633,7 +636,7 @@ p, role:admin, projects, update, *, allow`)
role.Policies = append(role.Policies, invalidPolicy)
projWithRole.Spec.Roles = append(projWithRole.Spec.Roles, role)
argoDB := db.NewDB("default", settingsMgr, kubeclientset)
projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projWithRole), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB)
projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projWithRole), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB, testEnableEventList)
request := &project.ProjectUpdateRequest{Project: projWithRole}
_, err := projectServer.Update(context.Background(), request)
assert.Contains(t, err.Error(), "effect must be: 'allow' or 'deny'")
@@ -652,7 +655,7 @@ p, role:admin, projects, update, *, allow`)
role.Policies = append(role.Policies, invalidPolicy)
projWithRole.Spec.Roles = append(projWithRole.Spec.Roles, role)
argoDB := db.NewDB("default", settingsMgr, kubeclientset)
projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projWithRole), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB)
projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projWithRole), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB, testEnableEventList)
request := &project.ProjectUpdateRequest{Project: projWithRole}
updateProj, err := projectServer.Update(context.Background(), request)
require.NoError(t, err)
@@ -667,7 +670,7 @@ p, role:admin, projects, update, *, allow`)
win := &v1alpha1.SyncWindow{Kind: "allow", Schedule: "* * * * *", Duration: "1h"}
projectWithSyncWindows.Spec.SyncWindows = append(projectWithSyncWindows.Spec.SyncWindows, win)
argoDB := db.NewDB("default", settingsMgr, kubeclientset)
projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projectWithSyncWindows), enforcer, sync.NewKeyLock(), sessionMgr, nil, projInformer, settingsMgr, argoDB)
projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projectWithSyncWindows), enforcer, sync.NewKeyLock(), sessionMgr, nil, projInformer, settingsMgr, argoDB, testEnableEventList)
res, err := projectServer.GetSyncWindowsState(ctx, &project.SyncWindowsQuery{Name: projectWithSyncWindows.Name})
require.NoError(t, err)
assert.Len(t, res.Windows, 1)
@@ -680,7 +683,7 @@ p, role:admin, projects, update, *, allow`)
win := &v1alpha1.SyncWindow{Kind: "allow", Schedule: "* * * * *", Duration: "1h"}
projectWithSyncWindows.Spec.SyncWindows = append(projectWithSyncWindows.Spec.SyncWindows, win)
argoDB := db.NewDB("default", settingsMgr, kubeclientset)
projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projectWithSyncWindows), enforcer, sync.NewKeyLock(), sessionMgr, nil, projInformer, settingsMgr, argoDB)
projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projectWithSyncWindows), enforcer, sync.NewKeyLock(), sessionMgr, nil, projInformer, settingsMgr, argoDB, testEnableEventList)
res, err := projectServer.GetSyncWindowsState(ctx, &project.SyncWindowsQuery{Name: "incorrect"})
assert.Contains(t, err.Error(), "not found")
assert.Nil(t, res)
@@ -698,7 +701,7 @@ p, role:admin, projects, update, *, allow`)
win := &v1alpha1.SyncWindow{Kind: "allow", Schedule: "* * * * *", Duration: "1h"}
projectWithSyncWindows.Spec.SyncWindows = append(projectWithSyncWindows.Spec.SyncWindows, win)
argoDB := db.NewDB("default", settingsMgr, kubeclientset)
projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projectWithSyncWindows), enforcer, sync.NewKeyLock(), sessionMgr, nil, projInformer, settingsMgr, argoDB)
projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projectWithSyncWindows), enforcer, sync.NewKeyLock(), sessionMgr, nil, projInformer, settingsMgr, argoDB, testEnableEventList)
_, err := projectServer.GetSyncWindowsState(ctx, &project.SyncWindowsQuery{Name: projectWithSyncWindows.Name})
assert.EqualError(t, err, "rpc error: code = PermissionDenied desc = permission denied: projects, get, test")
})

View File

@@ -188,18 +188,21 @@ func (s *Server) ListRepositories(ctx context.Context, q *repositorypkg.RepoQuer
}
// remove secrets
items = append(items, &appsv1.Repository{
Repo: repo.Repo,
Type: rType,
Name: repo.Name,
Username: repo.Username,
Insecure: repo.IsInsecure(),
EnableLFS: repo.EnableLFS,
EnableOCI: repo.EnableOCI,
Proxy: repo.Proxy,
NoProxy: repo.NoProxy,
Project: repo.Project,
ForceHttpBasicAuth: repo.ForceHttpBasicAuth,
InheritedCreds: repo.InheritedCreds,
Repo: repo.Repo,
Type: rType,
Name: repo.Name,
Username: repo.Username,
Insecure: repo.IsInsecure(),
EnableLFS: repo.EnableLFS,
EnableOCI: repo.EnableOCI,
Proxy: repo.Proxy,
NoProxy: repo.NoProxy,
Project: repo.Project,
ForceHttpBasicAuth: repo.ForceHttpBasicAuth,
InheritedCreds: repo.InheritedCreds,
GithubAppId: repo.GithubAppId,
GithubAppInstallationId: repo.GithubAppInstallationId,
GitHubAppEnterpriseBaseURL: repo.GitHubAppEnterpriseBaseURL,
})
}
}

View File

@@ -21,6 +21,7 @@ import (
"github.com/argoproj/argo-cd/v2/common"
"github.com/argoproj/argo-cd/v2/pkg/apiclient/repository"
repositorypkg "github.com/argoproj/argo-cd/v2/pkg/apiclient/repository"
appsv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1"
fakeapps "github.com/argoproj/argo-cd/v2/pkg/client/clientset/versioned/fake"
appinformer "github.com/argoproj/argo-cd/v2/pkg/client/informers/externalversions"
@@ -1057,3 +1058,35 @@ func TestGetRepository(t *testing.T) {
})
}
}
func TestDeleteRepository(t *testing.T) {
repositories := map[string]string{
"valid": "https://bitbucket.org/workspace/repo.git",
// Check a wrongly formatter repo as well, see https://github.com/argoproj/argo-cd/issues/20921
"invalid": "git clone https://bitbucket.org/workspace/repo.git",
}
kubeclientset := fake.NewSimpleClientset(&argocdCM, &argocdSecret)
settingsMgr := settings.NewSettingsManager(context.Background(), kubeclientset, testNamespace)
for name, repo := range repositories {
t.Run(name, func(t *testing.T) {
repoServerClient := mocks.RepoServerServiceClient{}
repoServerClient.On("TestRepository", mock.Anything, mock.Anything).Return(&apiclient.TestRepositoryResponse{}, nil)
repoServerClientset := mocks.Clientset{RepoServerServiceClient: &repoServerClient}
enforcer := newEnforcer(kubeclientset)
db := &dbmocks.ArgoDB{}
db.On("DeleteRepository", context.TODO(), repo, "default").Return(nil)
db.On("ListRepositories", context.TODO()).Return([]*appsv1.Repository{{Repo: repo, Project: "default"}}, nil)
db.On("GetRepository", context.TODO(), repo, "default").Return(&appsv1.Repository{Repo: repo, Project: "default"}, nil)
appLister, projLister := newAppAndProjLister(defaultProj)
s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projLister, testNamespace, settingsMgr)
resp, err := s.DeleteRepository(context.TODO(), &repository.RepoQuery{Repo: repo, AppProject: "default"})
require.NoError(t, err)
assert.Equal(t, repositorypkg.RepoResponse{}, *resp)
})
}
}

View File

@@ -229,6 +229,7 @@ type ArgoCDServerOpts struct {
ApplicationNamespaces []string
EnableProxyExtension bool
WebhookParallelism int
EnableK8sEvent []string
}
type ApplicationSetOpts struct {
@@ -885,7 +886,9 @@ func newArgoCDServiceSet(a *ArgoCDServer) *ArgoCDServiceSet {
projectLock,
a.settingsMgr,
a.projInformer,
a.ApplicationNamespaces)
a.ApplicationNamespaces,
a.EnableK8sEvent,
)
applicationSetService := applicationset.NewServer(
a.db,
@@ -907,9 +910,10 @@ func newArgoCDServiceSet(a *ArgoCDServer) *ArgoCDServiceSet {
a.ScmRootCAPath,
a.AllowedScmProviders,
a.EnableScmProviders,
a.EnableK8sEvent,
)
projectService := project.NewServer(a.Namespace, a.KubeClientset, a.AppClientset, a.enf, projectLock, a.sessionMgr, a.policyEnforcer, a.projInformer, a.settingsMgr, a.db)
projectService := project.NewServer(a.Namespace, a.KubeClientset, a.AppClientset, a.enf, projectLock, a.sessionMgr, a.policyEnforcer, a.projInformer, a.settingsMgr, a.db, a.EnableK8sEvent)
appsInAnyNamespaceEnabled := len(a.ArgoCDServerOpts.ApplicationNamespaces) > 0
settingsService := settings.NewServer(a.settingsMgr, a.RepoClientset, a, a.DisableAuth, appsInAnyNamespaceEnabled)
accountService := account.NewServer(a.sessionMgr, a.settingsMgr, a.enf)

View File

@@ -347,7 +347,7 @@ func TestNamespacedAppCreationWithoutForceUpdate(t *testing.T) {
}).
When().
IgnoreErrors().
CreateApp().
CreateApp("--dest-server", KubernetesInternalAPIServerAddr).
Then().
Expect(Error("", "existing application spec is different, use upsert flag to force update"))
}

View File

@@ -450,7 +450,7 @@ func TestAppCreationWithoutForceUpdate(t *testing.T) {
}).
When().
IgnoreErrors().
CreateApp().
CreateApp("--dest-server", KubernetesInternalAPIServerAddr).
Then().
Expect(Error("", "existing application spec is different, use upsert flag to force update"))
}

View File

@@ -1156,7 +1156,6 @@ func TestSimpleGitDirectoryGenerator(t *testing.T) {
expectedApps := []argov1alpha1.Application{
generateExpectedApp("kustomize-guestbook"),
generateExpectedApp("helm-guestbook"),
generateExpectedApp("ksonnet-guestbook"),
}
var expectedAppsNewNamespace []argov1alpha1.Application
@@ -1266,7 +1265,6 @@ func TestSimpleGitDirectoryGeneratorGoTemplate(t *testing.T) {
expectedApps := []argov1alpha1.Application{
generateExpectedApp("kustomize-guestbook"),
generateExpectedApp("helm-guestbook"),
generateExpectedApp("ksonnet-guestbook"),
}
var expectedAppsNewNamespace []argov1alpha1.Application

View File

@@ -4,6 +4,7 @@ import (
"encoding/json"
"fmt"
"os"
"slices"
log "github.com/sirupsen/logrus"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -225,7 +226,7 @@ func (a *Actions) prepareCreateAppArgs(args []string) []string {
"--repo", fixture.RepoURL(a.context.repoURLType),
}, args...)
if a.context.destName != "" {
if a.context.destName != "" && a.context.isDestServerInferred && !slices.Contains(args, "--dest-server") {
args = append(args, "--dest-name", a.context.destName)
} else {
args = append(args, "--dest-server", a.context.destServer)

View File

@@ -14,7 +14,7 @@ import (
"github.com/argoproj/argo-cd/v2/util/settings"
)
// this implements the "given" part of given/when/then
// Context implements the "given" part of given/when/then
type Context struct {
t *testing.T
path string
@@ -26,6 +26,7 @@ type Context struct {
appNamespace string
destServer string
destName string
isDestServerInferred bool
env string
parameters []string
namePrefix string
@@ -63,12 +64,13 @@ func GivenWithNamespace(t *testing.T, namespace string) *Context {
}
func GivenWithSameState(t *testing.T) *Context {
// ARGOCE_E2E_DEFAULT_TIMEOUT can be used to override the default timeout
// ARGOCD_E2E_DEFAULT_TIMEOUT can be used to override the default timeout
// for any context.
timeout := env.ParseNumFromEnv("ARGOCD_E2E_DEFAULT_TIMEOUT", 20, 0, 180)
return &Context{
t: t,
destServer: v1alpha1.KubernetesInternalAPIServerAddr,
destName: "in-cluster",
repoURLType: fixture.RepoURLTypeFile,
name: fixture.Name(),
timeout: timeout,
@@ -257,11 +259,13 @@ func (c *Context) Timeout(timeout int) *Context {
func (c *Context) DestServer(destServer string) *Context {
c.destServer = destServer
c.isDestServerInferred = false
return c
}
func (c *Context) DestName(destName string) *Context {
c.destName = destName
c.isDestServerInferred = true
return c
}

View File

@@ -0,0 +1,67 @@
package e2e
import (
"regexp"
"testing"
"github.com/stretchr/testify/assert"
"github.com/argoproj/gitops-engine/pkg/health"
"github.com/argoproj/gitops-engine/pkg/sync/common"
. "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1"
. "github.com/argoproj/argo-cd/v2/test/e2e/fixture"
. "github.com/argoproj/argo-cd/v2/test/e2e/fixture/app"
)
// Secret values shouldn't be exposed in error messages and the diff view
// when invalid secret is synced.
func TestMaskValuesInInvalidSecret(t *testing.T) {
sensitiveData := regexp.MustCompile(`SECRETVAL|U0VDUkVUVkFM|12345`)
Given(t).
Path("empty-dir").
When().
// valid secret
AddFile("secrets.yaml", `apiVersion: v1
kind: Secret
metadata:
name: secret
annotations:
app: test
stringData:
username: SECRETVAL
data:
password: U0VDUkVUVkFM
`).
CreateApp().
Sync().
Then().
Expect(SyncStatusIs(SyncStatusCodeSynced)).
Expect(HealthIs(health.HealthStatusHealthy)).
// secret data shouldn't be exposed in manifests output
And(func(app *Application) {
mnfs, _ := RunCli("app", "manifests", app.Name)
assert.False(t, sensitiveData.MatchString(mnfs))
}).
When().
// invalidate secret
PatchFile("secrets.yaml", `[{"op": "replace", "path": "/data/password", "value": 12345}]`).
Refresh(RefreshTypeHard).
IgnoreErrors().
Sync().
Then().
Expect(SyncStatusIs(SyncStatusCodeOutOfSync)).
Expect(OperationPhaseIs(common.OperationFailed)).
// secret data shouldn't be exposed in manifests, diff & error output for invalid secret
And(func(app *Application) {
mnfs, _ := RunCli("app", "manifests", app.Name)
assert.False(t, sensitiveData.MatchString(mnfs))
diff, _ := RunCli("app", "diff", app.Name)
assert.False(t, sensitiveData.MatchString(diff))
msg := app.Status.OperationState.Message
assert.False(t, sensitiveData.MatchString(msg))
})
}

View File

@@ -45,11 +45,9 @@ func TestListMatrixGenerator(t *testing.T) {
expectedApps := []argov1alpha1.Application{
generateExpectedApp("cluster1", "kustomize-guestbook"),
generateExpectedApp("cluster1", "helm-guestbook"),
generateExpectedApp("cluster1", "ksonnet-guestbook"),
generateExpectedApp("cluster2", "kustomize-guestbook"),
generateExpectedApp("cluster2", "helm-guestbook"),
generateExpectedApp("cluster2", "ksonnet-guestbook"),
}
var expectedAppsNewNamespace []argov1alpha1.Application
@@ -170,11 +168,9 @@ func TestClusterMatrixGenerator(t *testing.T) {
expectedApps := []argov1alpha1.Application{
generateExpectedApp("cluster1", "kustomize-guestbook"),
generateExpectedApp("cluster1", "helm-guestbook"),
generateExpectedApp("cluster1", "ksonnet-guestbook"),
generateExpectedApp("cluster2", "kustomize-guestbook"),
generateExpectedApp("cluster2", "helm-guestbook"),
generateExpectedApp("cluster2", "ksonnet-guestbook"),
}
var expectedAppsNewNamespace []argov1alpha1.Application
@@ -298,12 +294,10 @@ func TestMatrixTerminalMatrixGeneratorSelector(t *testing.T) {
expectedApps1 := []argov1alpha1.Application{
generateExpectedApp("cluster1", "kustomize-guestbook"),
generateExpectedApp("cluster1", "helm-guestbook"),
generateExpectedApp("cluster1", "ksonnet-guestbook"),
}
expectedApps2 := []argov1alpha1.Application{
generateExpectedApp("cluster2", "kustomize-guestbook"),
generateExpectedApp("cluster2", "helm-guestbook"),
generateExpectedApp("cluster2", "ksonnet-guestbook"),
}
Given(t).

View File

@@ -167,11 +167,9 @@ func TestClusterMergeGenerator(t *testing.T) {
expectedApps := []argov1alpha1.Application{
generateExpectedApp("cluster1", "kustomize-guestbook", "1"),
generateExpectedApp("cluster1", "helm-guestbook", "0"),
generateExpectedApp("cluster1", "ksonnet-guestbook", "0"),
generateExpectedApp("cluster2", "kustomize-guestbook", "0"),
generateExpectedApp("cluster2", "helm-guestbook", "2"),
generateExpectedApp("cluster2", "ksonnet-guestbook", "0"),
}
var expectedAppsNewNamespace []argov1alpha1.Application

View File

View File

@@ -1,9 +1,10 @@
import {DataLoader, NavigationManager, Notifications, NotificationsManager, PageContext, Popup, PopupManager, PopupProps} from 'argo-ui';
import {DataLoader, NavigationManager, NotificationType, Notifications, NotificationsManager, PageContext, Popup, PopupManager, PopupProps} from 'argo-ui';
import {createBrowserHistory} from 'history';
import * as PropTypes from 'prop-types';
import * as React from 'react';
import {Helmet} from 'react-helmet';
import {Redirect, Route, RouteComponentProps, Router, Switch} from 'react-router';
import {Subscription} from 'rxjs';
import applications from './applications';
import help from './help';
import login from './login';
@@ -19,6 +20,7 @@ import {Banner} from './ui-banner/ui-banner';
import userInfo from './user-info';
import {AuthSettings} from './shared/models';
import {PKCEVerification} from './login/components/pkce-verify';
import {getPKCERedirectURI, pkceLogin} from './login/components/utils';
import {SystemLevelExtension} from './shared/services/extensions-service';
services.viewPreferences.init();
@@ -86,28 +88,6 @@ async function isExpiredSSO() {
return false;
}
requests.onError.subscribe(async err => {
if (err.status === 401) {
if (history.location.pathname.startsWith('/login')) {
return;
}
const isSSO = await isExpiredSSO();
// location might change after async method call, so we need to check again.
if (history.location.pathname.startsWith('/login')) {
return;
}
// Query for basehref and remove trailing /.
// If basehref is the default `/` it will become an empty string.
const basehref = document.querySelector('head > base').getAttribute('href').replace(/\/$/, '');
if (isSSO) {
window.location.href = `${basehref}/auth/login?return_url=${encodeURIComponent(location.href)}`;
} else {
history.push(`/login?return_url=${encodeURIComponent(location.href)}`);
}
}
});
export class App extends React.Component<
{},
{popupProps: PopupProps; showVersionPanel: boolean; error: Error; navItems: NavItem[]; routes: Routes; extensionsLoaded: boolean; authSettings: AuthSettings}
@@ -126,6 +106,8 @@ export class App extends React.Component<
private navigationManager: NavigationManager;
private navItems: NavItem[];
private routes: Routes;
private popupPropsSubscription: Subscription;
private unauthorizedSubscription: Subscription;
constructor(props: {}) {
super(props);
@@ -135,11 +117,16 @@ export class App extends React.Component<
this.navigationManager = new NavigationManager(history);
this.navItems = navItems;
this.routes = routes;
this.popupPropsSubscription = null;
this.unauthorizedSubscription = null;
services.extensions.addEventListener('systemLevel', this.onAddSystemLevelExtension.bind(this));
}
public async componentDidMount() {
this.popupManager.popupProps.subscribe(popupProps => this.setState({popupProps}));
this.popupPropsSubscription = this.popupManager.popupProps.subscribe(popupProps => this.setState({popupProps}));
this.subscribeUnauthorized().then(subscription => {
this.unauthorizedSubscription = subscription;
});
const authSettings = await services.authService.settings();
const {trackingID, anonymizeUsers} = authSettings.googleAnalytics || {trackingID: '', anonymizeUsers: true};
const {loggedIn, username} = await services.users.get();
@@ -167,6 +154,15 @@ export class App extends React.Component<
this.setState({...this.state, navItems: this.navItems, routes: this.routes, extensionsLoaded: false, authSettings});
}
public componentWillUnmount() {
if (this.popupPropsSubscription) {
this.popupPropsSubscription.unsubscribe();
}
if (this.unauthorizedSubscription) {
this.unauthorizedSubscription.unsubscribe();
}
}
public render() {
if (this.state.error != null) {
const stack = this.state.error.stack;
@@ -239,7 +235,42 @@ export class App extends React.Component<
}
public getChildContext() {
return {history, apis: {popup: this.popupManager, notifications: this.notificationsManager, navigation: this.navigationManager}};
return {history, apis: {popup: this.popupManager, notifications: this.notificationsManager, navigation: this.navigationManager, baseHref: base}};
}
private async subscribeUnauthorized() {
return requests.onError.subscribe(async err => {
if (err.status === 401) {
if (history.location.pathname.startsWith('/login')) {
return;
}
const isSSO = await isExpiredSSO();
// location might change after async method call, so we need to check again.
if (history.location.pathname.startsWith('/login')) {
return;
}
// Query for basehref and remove trailing /.
// If basehref is the default `/` it will become an empty string.
const basehref = document.querySelector('head > base').getAttribute('href').replace(/\/$/, '');
if (isSSO) {
const authSettings = await services.authService.settings();
if (authSettings?.oidcConfig?.enablePKCEAuthentication) {
pkceLogin(authSettings.oidcConfig, getPKCERedirectURI().toString()).catch(err => {
this.getChildContext().apis.notifications.show({
type: NotificationType.Error,
content: err?.message || JSON.stringify(err)
});
});
} else {
window.location.href = `${basehref}/auth/login?return_url=${encodeURIComponent(location.href)}`;
}
} else {
history.push(`/login?return_url=${encodeURIComponent(location.href)}`);
}
}
});
}
private onAddSystemLevelExtension(extension: SystemLevelExtension) {

View File

@@ -3,6 +3,7 @@ import * as React from 'react';
import {Context} from '../../../shared/context';
import {services} from '../../../shared/services';
import {getAppUrl} from '../utils';
export const ApplicationsDetailsAppDropdown = (props: {appName: string}) => {
const [opened, setOpened] = React.useState(false);
@@ -42,7 +43,7 @@ export const ApplicationsDetailsAppDropdown = (props: {appName: string}) => {
})
.slice(0, 100) // take top 100 results after filtering to avoid performance issues
.map(app => (
<li key={app.metadata.name} onClick={() => ctx.navigation.goto(`/applications/${app.metadata.namespace}/${app.metadata.name}`)}>
<li key={app.metadata.name} onClick={() => ctx.navigation.goto(getAppUrl(app))}>
{app.metadata.name} {app.metadata.name === props.appName && ' (current)'}
</li>
))

View File

@@ -82,7 +82,6 @@ export class ApplicationDetails extends React.Component<RouteComponentProps<{app
};
private appChanged = new BehaviorSubject<appModels.Application>(null);
private appNamespace: string;
constructor(props: RouteComponentProps<{appnamespace: string; name: string}>) {
super(props);
@@ -95,11 +94,6 @@ export class ApplicationDetails extends React.Component<RouteComponentProps<{app
collapsedNodes: [],
...this.getExtensionsState()
};
if (typeof this.props.match.params.appnamespace === 'undefined') {
this.appNamespace = '';
} else {
this.appNamespace = this.props.match.params.appnamespace;
}
}
public componentDidMount() {
@@ -116,6 +110,13 @@ export class ApplicationDetails extends React.Component<RouteComponentProps<{app
services.extensions.removeEventListener('topBar', this.onExtensionsUpdate);
}
private getAppNamespace() {
if (typeof this.props.match.params.appnamespace === 'undefined') {
return '';
}
return this.props.match.params.appnamespace;
}
private onExtensionsUpdate = () => {
this.setState({...this.state, ...this.getExtensionsState()});
};
@@ -426,7 +427,7 @@ export class ApplicationDetails extends React.Component<RouteComponentProps<{app
loadingRenderer={() => <Page title='Application Details'>Loading...</Page>}
input={this.props.match.params.name}
load={name =>
combineLatest([this.loadAppInfo(name, this.props.match.params.appnamespace), services.viewPreferences.getPreferences(), q]).pipe(
combineLatest([this.loadAppInfo(name, this.getAppNamespace()), services.viewPreferences.getPreferences(), q]).pipe(
map(items => {
const application = items[0].application;
const pref = items[1].appDetails;
@@ -1170,8 +1171,8 @@ Are you sure you want to disable auto-sync and rollback application '${this.prop
update.spec.syncPolicy = {automated: null};
await services.applications.update(update);
}
await services.applications.rollback(this.props.match.params.name, this.appNamespace, revisionHistory.id);
this.appChanged.next(await services.applications.get(this.props.match.params.name, this.appNamespace));
await services.applications.rollback(this.props.match.params.name, this.getAppNamespace(), revisionHistory.id);
this.appChanged.next(await services.applications.get(this.props.match.params.name, this.getAppNamespace()));
this.setRollbackPanelVisible(-1);
}
} catch (e) {
@@ -1187,7 +1188,7 @@ Are you sure you want to disable auto-sync and rollback application '${this.prop
}
private async deleteApplication() {
await AppUtils.deleteApplication(this.props.match.params.name, this.appNamespace, this.appContext.apis);
await AppUtils.deleteApplication(this.props.match.params.name, this.getAppNamespace(), this.appContext.apis);
}
}

View File

@@ -37,7 +37,7 @@ export const ApplicationsTable = (props: {
keys: Key.ENTER,
action: () => {
if (selectedApp > -1) {
ctxh.navigation.goto(`/applications/${props.applications[selectedApp].metadata.name}`);
ctxh.navigation.goto(AppUtils.getAppUrl(props.applications[selectedApp]));
return true;
}
return false;
@@ -57,9 +57,7 @@ export const ApplicationsTable = (props: {
key={AppUtils.appInstanceName(app)}
className={`argo-table-list__row
applications-list__entry applications-list__entry--health-${app.status.health.status} ${selectedApp === i ? 'applications-tiles__selected' : ''}`}>
<div
className={`row applications-list__table-row`}
onClick={e => ctx.navigation.goto(`applications/${app.metadata.namespace}/${app.metadata.name}`, {}, {event: e})}>
<div className={`row applications-list__table-row`} onClick={e => ctx.navigation.goto(AppUtils.getAppUrl(app), {}, {event: e})}>
<div className='columns small-4'>
<div className='row'>
<div className=' columns small-2'>

View File

@@ -66,7 +66,7 @@ export const ApplicationTiles = ({applications, syncApplication, refreshApplicat
keys: Key.ENTER,
action: () => {
if (selectedApp > -1) {
ctxh.navigation.goto(`/applications/${applications[selectedApp].metadata.name}`);
ctxh.navigation.goto(AppUtils.getAppUrl(applications[selectedApp]));
return true;
}
return false;
@@ -118,9 +118,7 @@ export const ApplicationTiles = ({applications, syncApplication, refreshApplicat
}`}>
<div
className='row applications-tiles__wrapper'
onClick={e =>
ctx.navigation.goto(`applications/${app.metadata.namespace}/${app.metadata.name}`, {view: pref.appDetails.view}, {event: e})
}>
onClick={e => ctx.navigation.goto(AppUtils.getAppUrl(app), {view: pref.appDetails.view}, {event: e})}>
<div
className={`columns small-12 applications-list__info qe-applications-list-${AppUtils.appInstanceName(
app

View File

@@ -1471,3 +1471,10 @@ export const userMsgsList: {[key: string]: string} = {
groupNodes: `Since the number of pods has surpassed the threshold pod count of 15, you will now be switched to the group node view.
If you prefer the tree view, you can simply click on the Group Nodes toolbar button to deselect the current view.`
};
export function getAppUrl(app: appModels.Application): string {
if (typeof app.metadata.namespace === 'undefined') {
return `applications/${app.metadata.name}`;
}
return `applications/${app.metadata.namespace}/${app.metadata.name}`;
}

View File

@@ -136,7 +136,12 @@ export class Login extends React.Component<RouteComponentProps<{}>, State> {
this.setState({loginInProgress: false});
if (returnURL) {
const url = new URL(returnURL);
this.appContext.apis.navigation.goto(url.pathname + url.search);
let redirectURL = url.pathname + url.search;
// return url already contains baseHref, so we need to remove it
if (this.appContext.apis.baseHref != '/' && redirectURL.startsWith(this.appContext.apis.baseHref)) {
redirectURL = redirectURL.substring(this.appContext.apis.baseHref.length);
}
this.appContext.apis.navigation.goto(redirectURL);
} else {
this.appContext.apis.navigation.goto('/applications');
}

View File

@@ -2,6 +2,7 @@ import React, {useEffect, useState} from 'react';
import {RouteComponentProps} from 'react-router';
import {services} from '../../shared/services';
import {PKCECodeVerifier, PKCELoginError, getPKCERedirectURI, pkceCallback} from './utils';
import requests from '../../shared/services/requests';
import './pkce-verify.scss';
@@ -31,7 +32,7 @@ export const PKCEVerification = (props: RouteComponentProps<any>) => {
<div>
<h3>Error occurred: </h3>
<p>{error?.message || JSON.stringify(error)}</p>
<a href='/login'>Try to Login again</a>
<a href={requests.toAbsURL('/login')}>Try to Login again</a>
</div>
</div>
);

View File

@@ -13,6 +13,7 @@ import {
validateAuthResponse
} from 'oauth4webapi';
import {AuthSettings} from '../../shared/models';
import requests from '../../shared/services/requests';
export const discoverAuthServer = (issuerURL: URL): Promise<AuthorizationServer> => discoveryRequest(issuerURL).then(res => processDiscoveryResponse(issuerURL, res));
@@ -25,7 +26,7 @@ export const PKCECodeVerifier = {
export const getPKCERedirectURI = () => {
const currentOrigin = new URL(window.location.origin);
currentOrigin.pathname = '/pkce/verify';
currentOrigin.pathname = requests.toAbsURL('/pkce/verify');
return currentOrigin;
};
@@ -70,6 +71,12 @@ const validateAndGetOIDCForPKCE = async (oidcConfig: AuthSettings['oidcConfig'])
export const pkceLogin = async (oidcConfig: AuthSettings['oidcConfig'], redirectURI: string) => {
const {authorizationServer} = await validateAndGetOIDCForPKCE(oidcConfig);
// This sets the return path for the user after the pkce auth flow.
// This is ignored if the return path would be the login page as it would just loop.
if (!location.pathname.startsWith(requests.toAbsURL('/login'))) {
sessionStorage.setItem('return_url', location.pathname + location.search);
}
if (!authorizationServer.authorization_endpoint) {
throw new PKCELoginError('No Authorization Server endpoint found');
}
@@ -145,7 +152,18 @@ export const pkceCallback = async (queryParams: string, oidcConfig: AuthSettings
throw new PKCELoginError('No token in response');
}
document.cookie = `argocd.token=${result.id_token}; path=/`;
// This regex removes any leading or trailing '/' characters and the result is appended to a '/'.
// This is because when base href if not just '/' toAbsURL() will append a trailing '/'.
// Just removing a trailing '/' from the string would break when base href is not specified, defaulted to '/'.
// This pattern is used to handle both cases.
document.cookie = `argocd.token=${result.id_token}; path=/${requests.toAbsURL('').replace(/^\/|\/$/g, '')}`;
window.location.replace('/applications');
const returnURL = sessionStorage.getItem('return_url');
if (returnURL) {
sessionStorage.removeItem('return_url');
window.location.replace(returnURL);
} else {
window.location.replace(requests.toAbsURL('/applications'));
}
};

View File

@@ -671,7 +671,7 @@ export class ProjectDetails extends React.Component<RouteComponentProps<{name: s
/>
<AuthSettingsCtx.Consumer>
{authCtx =>
authCtx.appsInAnyNamespaceEnabled && (
authCtx?.appsInAnyNamespaceEnabled && (
<EditablePanel
save={item => this.saveProject(item)}
values={proj}

View File

@@ -5639,9 +5639,9 @@ http-proxy-agent@^5.0.0:
debug "4"
http-proxy-middleware@^2.0.0:
version "2.0.4"
resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-2.0.4.tgz#03af0f4676d172ae775cb5c33f592f40e1a4e07a"
integrity sha512-m/4FxX17SUvz4lJ5WPXOHDUuCwIqXLfLHs1s0uZ3oYjhoXlx9csYxaOa0ElDEJ+h8Q4iJ1s+lTMbiCa4EXIJqg==
version "2.0.7"
resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-2.0.7.tgz#915f236d92ae98ef48278a95dedf17e991936ec6"
integrity sha512-fgVY8AV7qU7z/MmXJ/rxwbrtQH4jBQ9m7kp3llF0liB7glmFeVZFBepQb32T3y8n8k2+AEYuMPCpinYW+/CuRA==
dependencies:
"@types/http-proxy" "^1.17.8"
http-proxy "^1.18.1"

View File

@@ -170,6 +170,7 @@ func cmpSupports(ctx context.Context, pluginSockFilePath, appPath, repoPath, fil
cfg, err := cmpClient.CheckPluginConfiguration(ctx, &empty.Empty{})
if err != nil {
log.Errorf("error checking plugin configuration %s, %v", fileName, err)
io.Close(conn)
return nil, nil, false
}
@@ -178,6 +179,7 @@ func cmpSupports(ctx context.Context, pluginSockFilePath, appPath, repoPath, fil
if namedPlugin {
return conn, cmpClient, true
}
io.Close(conn)
return nil, nil, false
}

View File

@@ -1,6 +1,7 @@
package path
import (
"errors"
"fmt"
"os"
"path/filepath"
@@ -51,6 +52,11 @@ func CheckOutOfBoundsSymlinks(basePath string) error {
}
return filepath.Walk(absBasePath, func(path string, info os.FileInfo, err error) error {
if err != nil {
// Ignore "no such file or directory" errors than can happen with
// temporary files such as .git/*.lock
if errors.Is(err, os.ErrNotExist) {
return nil
}
return fmt.Errorf("failed to walk for symlinks in %s: %w", absBasePath, err)
}
if files.IsSymlink(info) {

View File

@@ -484,16 +484,18 @@ func GetRefSources(ctx context.Context, sources argoappv1.ApplicationSources, pr
return refSources, nil
}
// ValidateDestination sets the 'Server' value of the ApplicationDestination, if it is not set.
// ValidateDestination sets the 'Server' or the `Name` value of the ApplicationDestination, if it is not set.
// NOTE: this function WILL write to the object pointed to by the 'dest' parameter.
//
// If an ApplicationDestination has a Name field, but has an empty Server (URL) field,
// ValidationDestination will look up the cluster by name (to get the server URL), and
// set the corresponding Server field value.
// set the corresponding Server field value. Same goes for the opposite case.
//
// It also checks:
// - If we used both name and server then we return an invalid spec error
func ValidateDestination(ctx context.Context, dest *argoappv1.ApplicationDestination, db db.ArgoDB) error {
if dest.IsServerInferred() && dest.IsNameInferred() {
return fmt.Errorf("application destination can't have both name and server inferred: %s %s", dest.Name, dest.Server)
}
if dest.Name != "" {
if dest.Server == "" {
server, err := getDestinationServer(ctx, db, dest.Name)
@@ -504,9 +506,20 @@ func ValidateDestination(ctx context.Context, dest *argoappv1.ApplicationDestina
return fmt.Errorf("application references destination cluster %s which does not exist", dest.Name)
}
dest.SetInferredServer(server)
} else if !dest.IsServerInferred() {
} else if !dest.IsServerInferred() && !dest.IsNameInferred() {
return fmt.Errorf("application destination can't have both name and server defined: %s %s", dest.Name, dest.Server)
}
} else if dest.Server != "" {
if dest.Name == "" {
serverName, err := getDestinationServerName(ctx, db, dest.Server)
if err != nil {
return fmt.Errorf("unable to find destination server: %w", err)
}
if serverName == "" {
return fmt.Errorf("application references destination cluster %s which does not exist", dest.Server)
}
dest.SetInferredName(serverName)
}
}
return nil
}
@@ -959,6 +972,22 @@ func getDestinationServer(ctx context.Context, db db.ArgoDB, clusterName string)
return servers[0], nil
}
func getDestinationServerName(ctx context.Context, db db.ArgoDB, server string) (string, error) {
if db == nil {
return "", fmt.Errorf("there are no clusters registered in the database")
}
cluster, err := db.GetCluster(ctx, server)
if err != nil {
return "", fmt.Errorf("error getting cluster name by server %q: %w", server, err)
}
if cluster.Name == "" {
return "", fmt.Errorf("there are no clusters with this URL: %s", server)
}
return cluster.Name, nil
}
func GetGlobalProjects(proj *argoappv1.AppProject, projLister applicationsv1.AppProjectLister, settingsManager *settings.SettingsManager) []*argoappv1.AppProject {
gps, err := settingsManager.GetGlobalProjectsSettings()
globalProjects := make([]*argoappv1.AppProject, 0)

View File

@@ -702,7 +702,7 @@ func TestValidatePermissions(t *testing.T) {
SourceRepos: []string{"http://some/where/else"},
},
}
cluster := &argoappv1.Cluster{Server: "https://127.0.0.1:6443"}
cluster := &argoappv1.Cluster{Server: "https://127.0.0.1:6443", Name: "test"}
db := &dbmocks.ArgoDB{}
db.On("GetCluster", context.Background(), spec.Destination.Server).Return(cluster, nil)
conditions, err := ValidatePermissions(context.Background(), &spec, &proj, db)
@@ -735,7 +735,7 @@ func TestValidatePermissions(t *testing.T) {
SourceRepos: []string{"http://some/where"},
},
}
cluster := &argoappv1.Cluster{Server: "https://127.0.0.1:6443"}
cluster := &argoappv1.Cluster{Server: "https://127.0.0.1:6443", Name: "test"}
db := &dbmocks.ArgoDB{}
db.On("GetCluster", context.Background(), spec.Destination.Server).Return(cluster, nil)
conditions, err := ValidatePermissions(context.Background(), &spec, &proj, db)
@@ -773,7 +773,7 @@ func TestValidatePermissions(t *testing.T) {
conditions, err := ValidatePermissions(context.Background(), &spec, &proj, db)
require.NoError(t, err)
assert.Len(t, conditions, 1)
assert.Contains(t, conditions[0].Message, "has not been configured")
assert.Contains(t, conditions[0].Message, "unable to find destination server")
})
t.Run("Destination cluster name does not exist", func(t *testing.T) {
@@ -834,8 +834,10 @@ func TestValidatePermissions(t *testing.T) {
}
db := &dbmocks.ArgoDB{}
db.On("GetCluster", context.Background(), spec.Destination.Server).Return(nil, fmt.Errorf("Unknown error occurred"))
_, err := ValidatePermissions(context.Background(), &spec, &proj, db)
require.Error(t, err)
conditions, err := ValidatePermissions(context.Background(), &spec, &proj, db)
require.NoError(t, err)
assert.Len(t, conditions, 1)
assert.Contains(t, conditions[0].Message, "Unknown error occurred")
})
t.Run("Destination cluster name resolves to valid server", func(t *testing.T) {
@@ -934,7 +936,7 @@ func TestValidateDestination(t *testing.T) {
}
appCond := ValidateDestination(context.Background(), &dest, nil)
require.NoError(t, appCond)
require.Error(t, appCond)
assert.False(t, dest.IsServerInferred())
})
@@ -1422,7 +1424,7 @@ func TestValidatePermissionsMultipleSources(t *testing.T) {
SourceRepos: []string{"http://some/where/else"},
},
}
cluster := &argoappv1.Cluster{Server: "https://127.0.0.1:6443"}
cluster := &argoappv1.Cluster{Server: "https://127.0.0.1:6443", Name: "test"}
db := &dbmocks.ArgoDB{}
db.On("GetCluster", context.Background(), spec.Destination.Server).Return(cluster, nil)
conditions, err := ValidatePermissions(context.Background(), &spec, &proj, db)

View File

@@ -18,9 +18,10 @@ import (
)
type AuditLogger struct {
kIf kubernetes.Interface
component string
ns string
kIf kubernetes.Interface
component string
ns string
enableEventLog map[string]bool
}
type EventInfo struct {
@@ -95,7 +96,15 @@ func (l *AuditLogger) logEvent(objMeta ObjectRef, gvk schema.GroupVersionKind, i
}
}
func (l *AuditLogger) enableK8SEventLog(info EventInfo) bool {
return l.enableEventLog["all"] || l.enableEventLog[info.Reason]
}
func (l *AuditLogger) LogAppEvent(app *v1alpha1.Application, info EventInfo, message, user string, eventLabels map[string]string) {
if !l.enableK8SEventLog(info) {
return
}
objectMeta := ObjectRef{
Name: app.ObjectMeta.Name,
Namespace: app.ObjectMeta.Namespace,
@@ -113,6 +122,10 @@ func (l *AuditLogger) LogAppEvent(app *v1alpha1.Application, info EventInfo, mes
}
func (l *AuditLogger) LogAppSetEvent(app *v1alpha1.ApplicationSet, info EventInfo, message, user string) {
if !l.enableK8SEventLog(info) {
return
}
objectMeta := ObjectRef{
Name: app.ObjectMeta.Name,
Namespace: app.ObjectMeta.Namespace,
@@ -127,6 +140,10 @@ func (l *AuditLogger) LogAppSetEvent(app *v1alpha1.ApplicationSet, info EventInf
}
func (l *AuditLogger) LogResourceEvent(res *v1alpha1.ResourceNode, info EventInfo, message, user string) {
if !l.enableK8SEventLog(info) {
return
}
objectMeta := ObjectRef{
Name: res.ResourceRef.Name,
Namespace: res.ResourceRef.Namespace,
@@ -145,6 +162,10 @@ func (l *AuditLogger) LogResourceEvent(res *v1alpha1.ResourceNode, info EventInf
}
func (l *AuditLogger) LogAppProjEvent(proj *v1alpha1.AppProject, info EventInfo, message, user string) {
if !l.enableK8SEventLog(info) {
return
}
objectMeta := ObjectRef{
Name: proj.ObjectMeta.Name,
Namespace: proj.ObjectMeta.Namespace,
@@ -158,10 +179,35 @@ func (l *AuditLogger) LogAppProjEvent(proj *v1alpha1.AppProject, info EventInfo,
l.logEvent(objectMeta, v1alpha1.AppProjectSchemaGroupVersionKind, info, message, nil, nil)
}
func NewAuditLogger(ns string, kIf kubernetes.Interface, component string) *AuditLogger {
func NewAuditLogger(ns string, kIf kubernetes.Interface, component string, enableK8sEvent []string) *AuditLogger {
return &AuditLogger{
ns: ns,
kIf: kIf,
component: component,
ns: ns,
kIf: kIf,
component: component,
enableEventLog: setK8sEventList(enableK8sEvent),
}
}
func setK8sEventList(enableK8sEvent []string) map[string]bool {
enableK8sEventList := make(map[string]bool)
for _, event := range enableK8sEvent {
if event == "all" {
enableK8sEventList = map[string]bool{
"all": true,
}
return enableK8sEventList
} else if event == "none" {
enableK8sEventList = map[string]bool{}
return enableK8sEventList
}
enableK8sEventList[event] = true
}
return enableK8sEventList
}
func DefaultEnableEventList() []string {
return []string{"all"}
}

View File

@@ -14,6 +14,13 @@ import (
argoappv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1"
)
const (
_somecomponent = "somecomponent"
_test = "test"
)
var testEnableEventLog []string = []string{_somecomponent, _test}
// Helper to capture log entries generated by the logger and return it as string
func captureLogEntries(run func()) string {
f := log.StandardLogger().Formatter
@@ -29,12 +36,12 @@ func captureLogEntries(run func()) string {
}
func TestNewAuditLogger(t *testing.T) {
logger := NewAuditLogger("default", fake.NewSimpleClientset(), "somecomponent")
logger := NewAuditLogger("default", fake.NewSimpleClientset(), _somecomponent, testEnableEventLog)
assert.NotNil(t, logger)
}
func TestLogAppProjEvent(t *testing.T) {
logger := NewAuditLogger("default", fake.NewSimpleClientset(), "somecomponent")
logger := NewAuditLogger("default", fake.NewSimpleClientset(), _somecomponent, testEnableEventLog)
assert.NotNil(t, logger)
proj := argoappv1.AppProject{
@@ -50,7 +57,7 @@ func TestLogAppProjEvent(t *testing.T) {
}
ei := EventInfo{
Reason: "test",
Reason: _test,
Type: "info",
}
@@ -63,10 +70,19 @@ func TestLogAppProjEvent(t *testing.T) {
assert.Contains(t, output, "reason=test")
assert.Contains(t, output, "type=info")
assert.Contains(t, output, "msg=\"This is a test message\"")
ei.Reason = "Unknown"
// If K8s Event Disable Log
output = captureLogEntries(func() {
logger.LogAppProjEvent(&proj, ei, "This is a test message", "")
})
assert.Empty(t, output)
}
func TestLogAppEvent(t *testing.T) {
logger := NewAuditLogger("default", fake.NewSimpleClientset(), "somecomponent")
logger := NewAuditLogger("default", fake.NewSimpleClientset(), _somecomponent, testEnableEventLog)
assert.NotNil(t, logger)
app := argoappv1.Application{
@@ -85,7 +101,7 @@ func TestLogAppEvent(t *testing.T) {
}
ei := EventInfo{
Reason: "test",
Reason: _test,
Type: "info",
}
@@ -100,10 +116,19 @@ func TestLogAppEvent(t *testing.T) {
assert.Contains(t, output, "reason=test")
assert.Contains(t, output, "type=info")
assert.Contains(t, output, "msg=\"This is a test message\"")
ei.Reason = "Unknown"
// If K8s Event Disable Log
output = captureLogEntries(func() {
logger.LogAppEvent(&app, ei, "This is a test message", "", nil)
})
assert.Empty(t, output)
}
func TestLogResourceEvent(t *testing.T) {
logger := NewAuditLogger("default", fake.NewSimpleClientset(), "somecomponent")
logger := NewAuditLogger("default", fake.NewSimpleClientset(), _somecomponent, testEnableEventLog)
assert.NotNil(t, logger)
res := argoappv1.ResourceNode{
@@ -118,7 +143,7 @@ func TestLogResourceEvent(t *testing.T) {
}
ei := EventInfo{
Reason: "test",
Reason: _test,
Type: "info",
}
@@ -131,4 +156,13 @@ func TestLogResourceEvent(t *testing.T) {
assert.Contains(t, output, "reason=test")
assert.Contains(t, output, "type=info")
assert.Contains(t, output, "msg=\"This is a test message\"")
ei.Reason = "Unknown"
// If K8s Event Disable Log
output = captureLogEntries(func() {
logger.LogResourceEvent(&res, ei, "This is a test message", "")
})
assert.Empty(t, output)
}

View File

@@ -35,11 +35,21 @@ func IsTruncatedCommitSHA(sha string) bool {
// SameURL returns whether or not the two repository URLs are equivalent in location
func SameURL(leftRepo, rightRepo string) bool {
normalLeft := NormalizeGitURL(leftRepo)
normalRight := NormalizeGitURL(rightRepo)
normalLeft := NormalizeGitURLAllowInvalid(leftRepo)
normalRight := NormalizeGitURLAllowInvalid(rightRepo)
return normalLeft != "" && normalRight != "" && normalLeft == normalRight
}
// Similar to NormalizeGitURL, except returning an original url if the url is invalid.
// Needed to allow a deletion of repos with invalid urls. See https://github.com/argoproj/argo-cd/issues/20921.
func NormalizeGitURLAllowInvalid(repo string) string {
normalized := NormalizeGitURL(repo)
if normalized == "" {
return repo
}
return normalized
}
// NormalizeGitURL normalizes a git URL for purposes of comparison, as well as preventing redundant
// local clones (by normalizing various forms of a URL to a consistent location).
// Prefer using SameURL() over this function when possible. This algorithm may change over time

View File

@@ -25,6 +25,7 @@ import (
"gopkg.in/yaml.v2"
"oras.land/oras-go/v2/registry/remote"
"oras.land/oras-go/v2/registry/remote/auth"
"oras.land/oras-go/v2/registry/remote/credentials"
"github.com/argoproj/argo-cd/v2/util/cache"
argoio "github.com/argoproj/argo-cd/v2/util/io"
@@ -441,13 +442,23 @@ func (c *nativeHelmChart) GetTags(chart string, noCache bool) (*TagsList, error)
}}
repoHost, _, _ := strings.Cut(tagsURL, "/")
credential := auth.StaticCredential(repoHost, auth.Credential{
Username: c.creds.Username,
Password: c.creds.Password,
})
// Try to fallback to the environment config, but we shouldn't error if the file is not set
if c.creds.Username == "" && c.creds.Password == "" {
store, _ := credentials.NewStoreFromDocker(credentials.StoreOptions{})
if store != nil {
credential = credentials.Credential(store)
}
}
repo.Client = &auth.Client{
Client: client,
Cache: nil,
Credential: auth.StaticCredential(repoHost, auth.Credential{
Username: c.creds.Username,
Password: c.creds.Password,
}),
Client: client,
Cache: nil,
Credential: credential,
}
ctx := context.Background()

View File

@@ -9,6 +9,7 @@ import (
"net/http/httptest"
"net/url"
"os"
"path/filepath"
"strings"
"testing"
@@ -214,17 +215,21 @@ func TestGetTagsFromUrl(t *testing.T) {
}
func TestGetTagsFromURLPrivateRepoAuthentication(t *testing.T) {
username := "my-username"
password := "my-password"
expectedAuthorization := "Basic bXktdXNlcm5hbWU6bXktcGFzc3dvcmQ=" // base64(user:password)
server := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
t.Logf("called %s", r.URL.Path)
authorization := r.Header.Get("Authorization")
if authorization == "" {
w.Header().Set("WWW-Authenticate", `Basic realm="helm repo to get tags"`)
w.WriteHeader(http.StatusUnauthorized)
return
}
t.Logf("authorization received %s", authorization)
assert.Equal(t, expectedAuthorization, authorization)
responseTags := TagsList{
Tags: []string{
@@ -274,8 +279,94 @@ func TestGetTagsFromURLPrivateRepoAuthentication(t *testing.T) {
t.Run(testCase.name, func(t *testing.T) {
client := NewClient(testCase.repoURL, Creds{
InsecureSkipVerify: true,
Username: "my-username",
Password: "my-password",
Username: username,
Password: password,
}, true, "", "")
tags, err := client.GetTags("mychart", true)
require.NoError(t, err)
assert.ElementsMatch(t, tags.Tags, []string{
"2.8.0",
"2.8.0-prerelease",
"2.8.0+build",
"2.8.0-prerelease+build",
"2.8.0-prerelease.1+build.1234",
})
})
}
}
func TestGetTagsFromURLEnvironmentAuthentication(t *testing.T) {
bearerToken := "Zm9vOmJhcg=="
expectedAuthorization := "Basic " + bearerToken
server := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
t.Logf("called %s", r.URL.Path)
authorization := r.Header.Get("Authorization")
if authorization == "" {
w.Header().Set("WWW-Authenticate", `Basic realm="helm repo to get tags"`)
w.WriteHeader(http.StatusUnauthorized)
return
}
assert.Equal(t, expectedAuthorization, authorization)
responseTags := TagsList{
Tags: []string{
"2.8.0",
"2.8.0-prerelease",
"2.8.0_build",
"2.8.0-prerelease_build",
"2.8.0-prerelease.1_build.1234",
},
}
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
err := json.NewEncoder(w).Encode(responseTags)
if err != nil {
t.Fatal(err)
}
}))
t.Cleanup(server.Close)
serverURL, err := url.Parse(server.URL)
require.NoError(t, err)
tempDir := t.TempDir()
configPath := filepath.Join(tempDir, "config.json")
t.Setenv("DOCKER_CONFIG", tempDir)
config := fmt.Sprintf(`{"auths":{"%s":{"auth":"%s"}}}`, server.URL, bearerToken)
require.NoError(t, os.WriteFile(configPath, []byte(config), 0o666))
testCases := []struct {
name string
repoURL string
}{
{
name: "should login correctly when the repo path is in the server root with http scheme",
repoURL: server.URL,
},
{
name: "should login correctly when the repo path is not in the server root with http scheme",
repoURL: fmt.Sprintf("%s/my-repo", server.URL),
},
{
name: "should login correctly when the repo path is in the server root without http scheme",
repoURL: serverURL.Host,
},
{
name: "should login correctly when the repo path is not in the server root without http scheme",
repoURL: fmt.Sprintf("%s/my-repo", serverURL.Host),
},
}
for _, testCase := range testCases {
t.Run(testCase.name, func(t *testing.T) {
client := NewClient(testCase.repoURL, Creds{
InsecureSkipVerify: true,
}, true, "", "")
tags, err := client.GetTags("mychart", true)