Compare commits

...

4 Commits

Author SHA1 Message Date
github-actions[bot]
a70b2293a0 Bump version to 2.13.9 on release-2.13 branch (#24404)
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-09-04 13:30:39 -04:00
Michael Crenshaw
b8ac09d326 fix(security): repository.GetDetailedProject exposes repo secrets (#24388)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
Co-authored-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2025-09-04 13:30:14 -04:00
Michael Crenshaw
bfa724719a fix(server): infer resource status health for apps-in-any-ns (#22944) (#23708)
Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
2025-07-09 17:07:56 -04:00
Blake Pettersson
df347d0d56 fix: do not normalize resource tracking on live crds (#22722) - cherrypick 2.13 (#22747)
Signed-off-by: Blake Pettersson <blake.pettersson@gmail.com>
Co-authored-by: Alexandre Gaudreault <alexandre_gaudreault@intuit.com>
2025-06-16 13:48:07 -04:00
18 changed files with 211 additions and 57 deletions

View File

@@ -1 +1 @@
2.13.8
2.13.9

View File

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

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.8
image: quay.io/argoproj/argocd:v2.13.9
imagePullPolicy: Always
name: argocd-applicationset-controller
ports:
@@ -22689,7 +22689,7 @@ spec:
- argocd
- admin
- redis-initial-password
image: quay.io/argoproj/argocd:v2.13.8
image: quay.io/argoproj/argocd:v2.13.9
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.8
image: quay.io/argoproj/argocd:v2.13.9
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.8
image: quay.io/argoproj/argocd:v2.13.9
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.8
image: quay.io/argoproj/argocd:v2.13.9
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.8
newTag: v2.13.9

View File

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

View File

@@ -23914,7 +23914,7 @@ spec:
key: applicationsetcontroller.webhook.parallelism.limit
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.13.8
image: quay.io/argoproj/argocd:v2.13.9
imagePullPolicy: Always
name: argocd-applicationset-controller
ports:
@@ -24049,7 +24049,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /shared/argocd-dex
image: quay.io/argoproj/argocd:v2.13.8
image: quay.io/argoproj/argocd:v2.13.9
imagePullPolicy: Always
name: copyutil
securityContext:
@@ -24137,7 +24137,7 @@ spec:
key: notificationscontroller.repo.server.plaintext
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.13.8
image: quay.io/argoproj/argocd:v2.13.9
imagePullPolicy: Always
livenessProbe:
tcpSocket:
@@ -24256,7 +24256,7 @@ spec:
- argocd
- admin
- redis-initial-password
image: quay.io/argoproj/argocd:v2.13.8
image: quay.io/argoproj/argocd:v2.13.9
imagePullPolicy: IfNotPresent
name: secret-init
securityContext:
@@ -24537,7 +24537,7 @@ spec:
value: /helm-working-dir
- name: HELM_DATA_HOME
value: /helm-working-dir
image: quay.io/argoproj/argocd:v2.13.8
image: quay.io/argoproj/argocd:v2.13.9
imagePullPolicy: Always
livenessProbe:
failureThreshold: 3
@@ -24589,7 +24589,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /var/run/argocd/argocd-cmp-server
image: quay.io/argoproj/argocd:v2.13.8
image: quay.io/argoproj/argocd:v2.13.9
name: copyutil
securityContext:
allowPrivilegeEscalation: false
@@ -24943,7 +24943,7 @@ spec:
key: applicationsetcontroller.enable.scm.providers
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.13.8
image: quay.io/argoproj/argocd:v2.13.9
imagePullPolicy: Always
livenessProbe:
httpGet:
@@ -25269,7 +25269,7 @@ spec:
key: controller.ignore.normalizer.jq.timeout
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.13.8
image: quay.io/argoproj/argocd:v2.13.9
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.8
image: quay.io/argoproj/argocd:v2.13.9
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.8
image: quay.io/argoproj/argocd:v2.13.9
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.8
image: quay.io/argoproj/argocd:v2.13.9
imagePullPolicy: Always
livenessProbe:
tcpSocket:
@@ -2036,7 +2036,7 @@ spec:
- argocd
- admin
- redis-initial-password
image: quay.io/argoproj/argocd:v2.13.8
image: quay.io/argoproj/argocd:v2.13.9
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.8
image: quay.io/argoproj/argocd:v2.13.9
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.8
image: quay.io/argoproj/argocd:v2.13.9
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.8
image: quay.io/argoproj/argocd:v2.13.9
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.8
image: quay.io/argoproj/argocd:v2.13.9
imagePullPolicy: Always
name: argocd-application-controller
ports:

16
manifests/install.yaml generated
View File

@@ -23031,7 +23031,7 @@ spec:
key: applicationsetcontroller.webhook.parallelism.limit
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.13.8
image: quay.io/argoproj/argocd:v2.13.9
imagePullPolicy: Always
name: argocd-applicationset-controller
ports:
@@ -23166,7 +23166,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /shared/argocd-dex
image: quay.io/argoproj/argocd:v2.13.8
image: quay.io/argoproj/argocd:v2.13.9
imagePullPolicy: Always
name: copyutil
securityContext:
@@ -23254,7 +23254,7 @@ spec:
key: notificationscontroller.repo.server.plaintext
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.13.8
image: quay.io/argoproj/argocd:v2.13.9
imagePullPolicy: Always
livenessProbe:
tcpSocket:
@@ -23354,7 +23354,7 @@ spec:
- argocd
- admin
- redis-initial-password
image: quay.io/argoproj/argocd:v2.13.8
image: quay.io/argoproj/argocd:v2.13.9
imagePullPolicy: IfNotPresent
name: secret-init
securityContext:
@@ -23607,7 +23607,7 @@ spec:
value: /helm-working-dir
- name: HELM_DATA_HOME
value: /helm-working-dir
image: quay.io/argoproj/argocd:v2.13.8
image: quay.io/argoproj/argocd:v2.13.9
imagePullPolicy: Always
livenessProbe:
failureThreshold: 3
@@ -23659,7 +23659,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /var/run/argocd/argocd-cmp-server
image: quay.io/argoproj/argocd:v2.13.8
image: quay.io/argoproj/argocd:v2.13.9
name: copyutil
securityContext:
allowPrivilegeEscalation: false
@@ -24011,7 +24011,7 @@ spec:
key: applicationsetcontroller.enable.scm.providers
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.13.8
image: quay.io/argoproj/argocd:v2.13.9
imagePullPolicy: Always
livenessProbe:
httpGet:
@@ -24337,7 +24337,7 @@ spec:
key: controller.ignore.normalizer.jq.timeout
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.13.8
image: quay.io/argoproj/argocd:v2.13.9
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.8
image: quay.io/argoproj/argocd:v2.13.9
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.8
image: quay.io/argoproj/argocd:v2.13.9
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.8
image: quay.io/argoproj/argocd:v2.13.9
imagePullPolicy: Always
livenessProbe:
tcpSocket:
@@ -1134,7 +1134,7 @@ spec:
- argocd
- admin
- redis-initial-password
image: quay.io/argoproj/argocd:v2.13.8
image: quay.io/argoproj/argocd:v2.13.9
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.8
image: quay.io/argoproj/argocd:v2.13.9
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.8
image: quay.io/argoproj/argocd:v2.13.9
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.8
image: quay.io/argoproj/argocd:v2.13.9
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.8
image: quay.io/argoproj/argocd:v2.13.9
imagePullPolicy: Always
name: argocd-application-controller
ports:

View File

@@ -5,6 +5,7 @@ import (
"net/url"
"strings"
"github.com/argoproj/argo-cd/v2/common"
"github.com/argoproj/argo-cd/v2/util/cert"
"github.com/argoproj/argo-cd/v2/util/git"
"github.com/argoproj/argo-cd/v2/util/helm"
@@ -283,6 +284,33 @@ func (m *Repository) StringForLogging() string {
return fmt.Sprintf("&Repository{Repo: %q, Type: %q, Name: %q, Project: %q}", m.Repo, m.Type, m.Name, m.Project)
}
// Sanitized returns a copy of the Repository with sensitive information removed.
func (repo *Repository) Sanitized() *Repository {
return &Repository{
Repo: repo.Repo,
Type: repo.Type,
Name: repo.Name,
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,
}
}
func (repo *Repository) Normalize() *Repository {
if repo.Type == "" {
repo.Type = common.DefaultRepoType
}
return repo
}
// Repositories defines a list of Repository configurations
type Repositories []*Repository

View File

@@ -1918,6 +1918,30 @@ type Cluster struct {
Annotations map[string]string `json:"annotations,omitempty" protobuf:"bytes,13,opt,name=annotations"`
}
func (c *Cluster) Sanitized() *Cluster {
return &Cluster{
ID: c.ID,
Server: c.Server,
Name: c.Name,
Project: c.Project,
Namespaces: c.Namespaces,
Shard: c.Shard,
Labels: c.Labels,
Annotations: c.Annotations,
ClusterResources: c.ClusterResources,
ConnectionState: c.ConnectionState,
ServerVersion: c.ServerVersion,
Info: c.Info,
RefreshRequestedAt: c.RefreshRequestedAt,
Config: ClusterConfig{
AWSAuthConfig: c.Config.AWSAuthConfig,
TLSClientConfig: TLSClientConfig{
Insecure: c.Config.Insecure,
},
},
}
}
// Equals returns true if two cluster objects are considered to be equal
func (c *Cluster) Equals(other *Cluster) bool {
if c.Server != other.Server {

View File

@@ -4251,3 +4251,58 @@ func TestAppProject_ValidateDestinationServiceAccount(t *testing.T) {
}
}
}
func TestSanitized(t *testing.T) {
now := metav1.Now()
cluster := &Cluster{
ID: "123",
Server: "https://example.com",
Name: "example",
ServerVersion: "v1.0.0",
Namespaces: []string{"default", "kube-system"},
Project: "default",
Labels: map[string]string{
"env": "production",
},
Annotations: map[string]string{
"annotation-key": "annotation-value",
},
ConnectionState: ConnectionState{
Status: ConnectionStatusSuccessful,
Message: "Connection successful",
ModifiedAt: &now,
},
Config: ClusterConfig{
Username: "admin",
Password: "password123",
BearerToken: "abc",
TLSClientConfig: TLSClientConfig{
Insecure: true,
},
ExecProviderConfig: &ExecProviderConfig{
Command: "test",
},
},
}
assert.Equal(t, &Cluster{
ID: "123",
Server: "https://example.com",
Name: "example",
ServerVersion: "v1.0.0",
Namespaces: []string{"default", "kube-system"},
Project: "default",
Labels: map[string]string{"env": "production"},
Annotations: map[string]string{"annotation-key": "annotation-value"},
ConnectionState: ConnectionState{
Status: ConnectionStatusSuccessful,
Message: "Connection successful",
ModifiedAt: &now,
},
Config: ClusterConfig{
TLSClientConfig: TLSClientConfig{
Insecure: true,
},
},
}, cluster.Sanitized())
}

View File

@@ -2646,7 +2646,7 @@ func (s *Server) GetApplicationSyncWindows(ctx context.Context, q *application.A
func (s *Server) inferResourcesStatusHealth(app *appv1.Application) {
if app.Status.ResourceHealthSource == appv1.ResourceHealthLocationAppTree {
tree := &appv1.ApplicationTree{}
if err := s.cache.GetAppResourcesTree(app.Name, tree); err == nil {
if err := s.cache.GetAppResourcesTree(app.InstanceName(s.ns), tree); err == nil {
healthByKey := map[kube.ResourceKey]*appv1.HealthStatus{}
for _, node := range tree.Nodes {
healthByKey[kube.NewResourceKey(node.Group, node.Kind, node.Namespace, node.Name)] = node.Health

View File

@@ -457,19 +457,8 @@ func (s *Server) RotateAuth(ctx context.Context, q *cluster.ClusterQuery) (*clus
}
func (s *Server) toAPIResponse(clust *appv1.Cluster) *appv1.Cluster {
clust = clust.Sanitized()
_ = s.cache.GetClusterInfo(clust.Server, &clust.Info)
clust.Config.Password = ""
clust.Config.BearerToken = ""
clust.Config.TLSClientConfig.KeyData = nil
if clust.Config.ExecProviderConfig != nil {
// We can't know what the user has put into args or
// env vars on the exec provider that might be sensitive
// (e.g. --private-key=XXX, PASSWORD=XXX)
// Implicitly assumes the command executable name is non-sensitive
clust.Config.ExecProviderConfig.Env = make(map[string]string)
clust.Config.ExecProviderConfig.Args = nil
}
// populate deprecated fields for backward compatibility
// nolint:staticcheck
clust.ServerVersion = clust.Info.ServerVersion

View File

@@ -311,12 +311,20 @@ func (s *Server) GetDetailedProject(ctx context.Context, q *project.ProjectQuery
}
proj.NormalizeJWTTokens()
globalProjects := argo.GetGlobalProjects(proj, listersv1alpha1.NewAppProjectLister(s.projInformer.GetIndexer()), s.settingsMgr)
var apiRepos []*v1alpha1.Repository
for _, repo := range repositories {
apiRepos = append(apiRepos, repo.Normalize().Sanitized())
}
var apiClusters []*v1alpha1.Cluster
for _, cluster := range clusters {
apiClusters = append(apiClusters, cluster.Sanitized())
}
return &project.DetailedProjectsResponse{
GlobalProjects: globalProjects,
Project: proj,
Repositories: repositories,
Clusters: clusters,
Repositories: apiRepos,
Clusters: apiClusters,
}, err
}

View File

@@ -315,7 +315,7 @@ func TestRepositoryServer(t *testing.T) {
testRepo := &appsv1.Repository{
Repo: url,
Type: "git",
Username: "foo",
Username: "",
InheritedCreds: true,
}
db.On("ListRepositories", context.TODO()).Return([]*appsv1.Repository{testRepo}, nil)

View File

@@ -6,6 +6,7 @@ import (
"regexp"
"strings"
kubeutil "github.com/argoproj/gitops-engine/pkg/utils/kube"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"github.com/argoproj/argo-cd/v2/common"
@@ -241,6 +242,11 @@ func (rt *resourceTracking) Normalize(config, live *unstructured.Unstructured, l
return nil
}
if kubeutil.IsCRD(live) {
// CRDs don't get tracking annotations.
return nil
}
annotation, err := argokube.GetAppInstanceAnnotation(config, common.AnnotationKeyAppInstance)
if err != nil {
return err

View File

@@ -203,6 +203,50 @@ func TestResourceIdNormalizer_Normalize(t *testing.T) {
assert.False(t, hasOldLabel)
}
func TestResourceIdNormalizer_NormalizeCRD(t *testing.T) {
rt := NewResourceTracking()
// live object is a CRD resource
liveObj := &unstructured.Unstructured{
Object: map[string]any{
"apiVersion": "apiextensions.k8s.io/v1",
"kind": "CustomResourceDefinition",
"metadata": map[string]any{
"name": "crontabs.stable.example.com",
"labels": map[string]any{
common.LabelKeyAppInstance: "my-app",
},
},
"spec": map[string]any{
"group": "stable.example.com",
"scope": "Namespaced",
},
},
}
// config object is a CRD resource
configObj := &unstructured.Unstructured{
Object: map[string]any{
"apiVersion": "apiextensions.k8s.io/v1",
"kind": "CustomResourceDefinition",
"metadata": map[string]any{
"name": "crontabs.stable.example.com",
"labels": map[string]any{
common.LabelKeyAppInstance: "my-app",
},
},
"spec": map[string]any{
"group": "stable.example.com",
"scope": "Namespaced",
},
},
}
require.NoError(t, rt.Normalize(configObj, liveObj, common.LabelKeyAppInstance, string(TrackingMethodAnnotation)))
// the normalization should not apply any changes to the live object
require.NotContains(t, liveObj.GetAnnotations(), common.AnnotationKeyAppInstance)
}
func TestResourceIdNormalizer_Normalize_ConfigHasOldLabel(t *testing.T) {
rt := NewResourceTracking()