mirror of
https://github.com/argoproj/argo-cd.git
synced 2026-02-20 17:48:47 +01:00
Compare commits
28 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2bcef48772 | ||
|
|
cb5d6f5ef7 | ||
|
|
2913d5fcb5 | ||
|
|
edd2358f79 | ||
|
|
e98f483bfd | ||
|
|
e2250bad87 | ||
|
|
a444a05e8f | ||
|
|
f075c5acd3 | ||
|
|
f58b8070f1 | ||
|
|
b2e875323c | ||
|
|
6fea008447 | ||
|
|
ffbf9d5911 | ||
|
|
ebeae20ff4 | ||
|
|
3ae374ce22 | ||
|
|
3d2c010dbe | ||
|
|
b6e6104dbc | ||
|
|
a8ce6772b8 | ||
|
|
5d131c5251 | ||
|
|
d6a04a3642 | ||
|
|
4f37dd880a | ||
|
|
20f0fc6786 | ||
|
|
4ced513335 | ||
|
|
0d2471b3f9 | ||
|
|
226a670fe6 | ||
|
|
2933154a5c | ||
|
|
ba866bfc16 | ||
|
|
6e4c8fd53d | ||
|
|
15046b992e |
3
.github/workflows/release.yaml
vendored
3
.github/workflows/release.yaml
vendored
@@ -77,7 +77,8 @@ jobs:
|
||||
- name: Set GORELEASER_PREVIOUS_TAG # Workaround, GoReleaser uses 'git-describe' to determine a previous tag. Our tags are created in release branches.
|
||||
run: |
|
||||
set -xue
|
||||
echo "GORELEASER_PREVIOUS_TAG=$(go run hack/get-previous-release/get-previous-version-for-release-notes.go ${{ github.ref_name }})" >> $GITHUB_ENV
|
||||
GORELEASER_PREVIOUS_TAG=$(go run hack/get-previous-release/get-previous-version-for-release-notes.go ${{ github.ref_name }}) || exit 1
|
||||
echo "GORELEASER_PREVIOUS_TAG=$GORELEASER_PREVIOUS_TAG" >> $GITHUB_ENV
|
||||
|
||||
- name: Set environment variables for ldflags
|
||||
id: set_ldflag
|
||||
|
||||
@@ -26,7 +26,11 @@ func NewGithubService(token, url, owner, repo string, labels []string) (PullRequ
|
||||
httpClient := &http.Client{}
|
||||
var client *github.Client
|
||||
if url == "" {
|
||||
client = github.NewClient(httpClient).WithAuthToken(token)
|
||||
if token == "" {
|
||||
client = github.NewClient(httpClient)
|
||||
} else {
|
||||
client = github.NewClient(httpClient).WithAuthToken(token)
|
||||
}
|
||||
} else {
|
||||
var err error
|
||||
client, err = github.NewClient(httpClient).WithEnterpriseURLs(url, url)
|
||||
|
||||
@@ -25,7 +25,11 @@ func NewGithubProvider(organization string, token string, url string, allBranche
|
||||
httpClient := &http.Client{}
|
||||
var client *github.Client
|
||||
if url == "" {
|
||||
client = github.NewClient(httpClient).WithAuthToken(token)
|
||||
if token == "" {
|
||||
client = github.NewClient(httpClient)
|
||||
} else {
|
||||
client = github.NewClient(httpClient).WithAuthToken(token)
|
||||
}
|
||||
} else {
|
||||
var err error
|
||||
client, err = github.NewClient(httpClient).WithEnterpriseURLs(url, url)
|
||||
|
||||
@@ -80,15 +80,15 @@ func setApplicationHealth(resources []managedResource, statuses []appv1.Resource
|
||||
appHealth.Status = healthStatus.Status
|
||||
}
|
||||
}
|
||||
// if the status didn't change, don't update the timestamp
|
||||
if app.Status.Health.Status == appHealth.Status && app.Status.Health.LastTransitionTime != nil {
|
||||
appHealth.LastTransitionTime = app.Status.Health.LastTransitionTime
|
||||
} else {
|
||||
now := metav1.Now()
|
||||
appHealth.LastTransitionTime = &now
|
||||
}
|
||||
if persistResourceHealth {
|
||||
app.Status.ResourceHealthSource = appv1.ResourceHealthLocationInline
|
||||
// if the status didn't change, don't update the timestamp
|
||||
if app.Status.Health.Status == appHealth.Status && app.Status.Health.LastTransitionTime != nil {
|
||||
appHealth.LastTransitionTime = app.Status.Health.LastTransitionTime
|
||||
} else {
|
||||
now := metav1.Now()
|
||||
appHealth.LastTransitionTime = &now
|
||||
}
|
||||
} else {
|
||||
app.Status.ResourceHealthSource = appv1.ResourceHealthLocationAppTree
|
||||
}
|
||||
|
||||
@@ -109,6 +109,7 @@ func TestSetApplicationHealth_ResourceHealthNotPersisted(t *testing.T) {
|
||||
healthStatus, err := setApplicationHealth(resources, resourceStatuses, lua.ResourceHealthOverrides{}, app, false)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, health.HealthStatusDegraded, healthStatus.Status)
|
||||
assert.NotNil(t, healthStatus.LastTransitionTime)
|
||||
|
||||
assert.Nil(t, resourceStatuses[0].Health)
|
||||
}
|
||||
|
||||
@@ -1,2 +1,5 @@
|
||||
This page is populated for released Argo CD versions. Use the version selector to view this table for a specific
|
||||
version.
|
||||
| Argo CD version | Kubernetes versions |
|
||||
|-----------------|---------------------|
|
||||
| 3.0 | v1.32, v1.31, v1.30, v1.29 |
|
||||
| 2.14 | v1.31, v1.30, v1.29, v1.28 |
|
||||
| 2.13 | v1.30, v1.29, v1.28, v1.27 |
|
||||
|
||||
@@ -35,25 +35,27 @@ Starting from 3.0, this flag is removed and the logs RBAC is enforced by default
|
||||
|
||||
#### Detection
|
||||
|
||||
Users who have `server.rbac.log.enforce.enable: "true"` in their `argocd-cm` ConfigMap, are unaffected by this change.
|
||||
Users who have `server.rbac.log.enforce.enable: "true"` in their `argocd-cm` ConfigMap, are unaffected by this change.
|
||||
|
||||
Users who have `policy.default: role:readonly` or `policy.default: role:admin` in their `argocd-rbac-cm` ConfigMap, are unaffected.
|
||||
Users who have `policy.default: role:readonly` or `policy.default: role:admin` in their `argocd-rbac-cm` ConfigMap, are unaffected.
|
||||
|
||||
Users who don't have a `policy.default` in their `argocd-rbac-cm` ConfigMap, and either have `server.rbac.log.enforce.enable` set to `false` or don't have this setting at all in their `argocd-cm` ConfigMap are affected and should perform the below remediation steps.
|
||||
Users who don't have a `policy.default` in their `argocd-rbac-cm` ConfigMap, and either have `server.rbac.log.enforce.enable` set to `false` or don't have this setting at all in their `argocd-cm` ConfigMap are affected and should perform the below remediation steps.
|
||||
|
||||
After the upgrade, it is recommended to remove the setting `server.rbac.log.enforce.enable` from `argocd-cm` ConfigMap, if it was there before the upgrade.
|
||||
After the upgrade, it is recommended to remove the setting `server.rbac.log.enforce.enable` from `argocd-cm` ConfigMap, if it was there before the upgrade.
|
||||
|
||||
#### Remediation
|
||||
|
||||
##### Quick remediation (global change)
|
||||
For users with an existing default policy with a custom role, add this policy to `policy.csv` for your custom role: `p, role:<YOUR_DEFAULT_ROLE>, logs, get, */*, allow`.
|
||||
For users without a default policy, add this policy to `policy.csv`: `p, role:global-log-viewer, logs, get, */*, allow` and add the default policy for this role: `policy.default: role:global-log-viewer`
|
||||
##### Quick remediation (global change)
|
||||
|
||||
For users with an existing default policy with a custom role, add this policy to `policy.csv` for your custom role: `p, role:<YOUR_DEFAULT_ROLE>, logs, get, */*, allow`.
|
||||
For users without a default policy, add this policy to `policy.csv`: `p, role:global-log-viewer, logs, get, */*, allow` and add the default policy for this role: `policy.default: role:global-log-viewer`
|
||||
|
||||
##### Recommended remediation (per-policy change)
|
||||
Explicitly add a `logs, get` policy to every role that has a policy for `applications, get` or for `applications, *`.
|
||||
This is the recommended way to maintain the principle of least privilege.
|
||||
Similar to the way access to Applications are currently managed, access to logs can be either granted on a Project scope level (Project resource) or on the `argocd-rbac-cm` ConfigMap level.
|
||||
See this [example](../upgrading/2.3-2.4.md#example-1) for more details.
|
||||
|
||||
Explicitly add a `logs, get` policy to every role that has a policy for `applications, get` or for `applications, *`.
|
||||
This is the recommended way to maintain the principle of least privilege.
|
||||
Similar to the way access to Applications are currently managed, access to logs can be either granted on a Project scope level (Project resource) or on the `argocd-rbac-cm` ConfigMap level.
|
||||
See this [example](../upgrading/2.3-2.4.md#example-1) for more details.
|
||||
|
||||
### Default `resource.exclusions` configurations
|
||||
|
||||
@@ -63,7 +65,7 @@ which we exclude for performance reasons, reducing connections and load to the K
|
||||
|
||||
The excluded Kinds are:
|
||||
|
||||
- **Kubernetes Resources**: `Endpoints`, `EndpointSlice`, `APIService`, `Lease`, `SelfSubjectReview`, `TokenReview`, `LocalSubjectAccessReview`, `SelfSubjectAccessReview`, `SelfSubjectRulesReview`, `SubjectAccessReview`, `CertificateSigningRequest`, `PolicyReport` and `ClusterPolicyReport`.
|
||||
- **Kubernetes Resources**: `Endpoints`, `EndpointSlice`, `Lease`, `SelfSubjectReview`, `TokenReview`, `LocalSubjectAccessReview`, `SelfSubjectAccessReview`, `SelfSubjectRulesReview`, `SubjectAccessReview`, `CertificateSigningRequest`, `PolicyReport` and `ClusterPolicyReport`.
|
||||
- **Cert Manager**: `CertificateRequest`.
|
||||
- **Kyverno**: `EphemeralReport`, `ClusterEphemeralReport`, `AdmissionReport`, `ClusterAdmissionReport`, `BackgroundScanReport`, `ClusterBackgroundScanReport` and `UpdateRequest`.
|
||||
- **Cilium**: `CiliumIdentity`, `CiliumEndpoint` and `CiliumEndpointSlice`.
|
||||
@@ -216,26 +218,28 @@ spec:
|
||||
namespace: guestbook
|
||||
```
|
||||
|
||||
### Upgraded Helm version with breaking changes
|
||||
Helm was upgraded to 3.17.1.
|
||||
This may require changing your `values.yaml` files for subcharts, if the `values.yaml` contain a section with a `null` object.
|
||||
See related issue in [Helm GitHub repository](https://github.com/helm/helm/issues/12469)
|
||||
See Helm 3.17.1 [release notes](https://github.com/helm/helm/releases/tag/v3.17.1)
|
||||
Example of such a [problem and resolution](https://github.com/argoproj/argo-cd/pull/22035/files)
|
||||
### Upgraded Helm version with breaking changes
|
||||
|
||||
Helm was upgraded to 3.17.1.
|
||||
This may require changing your `values.yaml` files for subcharts, if the `values.yaml` contain a section with a `null` object.
|
||||
See related issue in [Helm GitHub repository](https://github.com/helm/helm/issues/12469)
|
||||
See Helm 3.17.1 [release notes](https://github.com/helm/helm/releases/tag/v3.17.1)
|
||||
Example of such a [problem and resolution](https://github.com/argoproj/argo-cd/pull/22035/files)
|
||||
Explanation:
|
||||
|
||||
- Prior to Helm 3.17.1, `null` object in `values.yaml` resulted in a warning: `cannot overwrite table with non table` upon performing `helm template`, and the resulting K8s object was not overridden with the invalid `null` value.
|
||||
- In Helm 3.17.1, this behavior changed and `null` object in `values.yaml` still results in this warning upon performing `helm template`, but the resulting K8s object will be overridden with the invalid `null` value.
|
||||
- To resolve the issue, identify `values.yaml` with `null` object values, and remove those `null` values.
|
||||
- To resolve the issue, identify `values.yaml` with `null` object values, and remove those `null` values.
|
||||
|
||||
### Use Annotation-Based Tracking by Default
|
||||
|
||||
The default behavior for [tracking resources](../../user-guide/resource_tracking.md) has changed to use annotation-based
|
||||
tracking instead of label-based tracking. Annotation-based tracking is more reliable and less prone to errors caused by
|
||||
The default behavior for [tracking resources](../../user-guide/resource_tracking.md) has changed to use annotation-based
|
||||
tracking instead of label-based tracking. Annotation-based tracking is more reliable and less prone to errors caused by
|
||||
external code copying tracking labels from one resource to another.
|
||||
|
||||
#### Detection
|
||||
|
||||
To detect if you are impacted, check the `argocd-cm` ConfigMap for the `application.resourceTrackingMethod` field. If it
|
||||
To detect if you are impacted, check the `argocd-cm` ConfigMap for the `application.resourceTrackingMethod` field. If it
|
||||
unset or is set to `label`, you are using label-based tracking. If it is set to `annotation`, you are already using
|
||||
annotation-based tracking and are not impacted by this change.
|
||||
|
||||
@@ -315,6 +319,7 @@ Example of a status field in the Application CR persisting health:
|
||||
status:
|
||||
health:
|
||||
status: Healthy
|
||||
lastTransitionTime: "2025-01-01T00:00:00Z"
|
||||
resources:
|
||||
- group: apps
|
||||
health:
|
||||
@@ -334,6 +339,7 @@ Example of a status field in the Application CR _not_ persisting health:
|
||||
status:
|
||||
health:
|
||||
status: Healthy
|
||||
lastTransitionTime: "2025-01-01T00:00:00Z"
|
||||
resourceHealthSource: appTree
|
||||
resources:
|
||||
- group: apps
|
||||
|
||||
4
go.mod
4
go.mod
@@ -42,7 +42,7 @@ require (
|
||||
github.com/gobwas/glob v0.2.3
|
||||
github.com/gogits/go-gogs-client v0.0.0-20210131175652-1d7215cd8d85
|
||||
github.com/gogo/protobuf v1.3.2
|
||||
github.com/golang-jwt/jwt/v5 v5.2.1
|
||||
github.com/golang-jwt/jwt/v5 v5.2.2
|
||||
github.com/golang/protobuf v1.5.4
|
||||
github.com/google/btree v1.1.3
|
||||
github.com/google/go-cmp v0.7.0
|
||||
@@ -185,7 +185,7 @@ require (
|
||||
github.com/go-openapi/strfmt v0.23.0 // indirect
|
||||
github.com/go-openapi/swag v0.23.0 // indirect
|
||||
github.com/go-openapi/validate v0.24.0 // indirect
|
||||
github.com/golang-jwt/jwt/v4 v4.5.1 // indirect
|
||||
github.com/golang-jwt/jwt/v4 v4.5.2 // indirect
|
||||
github.com/golang/glog v1.2.4 // indirect
|
||||
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect
|
||||
github.com/google/gnostic-models v0.6.9 // indirect
|
||||
|
||||
8
go.sum
8
go.sum
@@ -362,10 +362,10 @@ github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||
github.com/golang-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg=
|
||||
github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
|
||||
github.com/golang-jwt/jwt/v4 v4.5.1 h1:JdqV9zKUdtaa9gdPlywC3aeoEsR681PlKC+4F5gQgeo=
|
||||
github.com/golang-jwt/jwt/v4 v4.5.1/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
|
||||
github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk=
|
||||
github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
|
||||
github.com/golang-jwt/jwt/v4 v4.5.2 h1:YtQM7lnr8iZ+j5q71MGKkNw9Mn7AjHM68uc9g5fXeUI=
|
||||
github.com/golang-jwt/jwt/v4 v4.5.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
|
||||
github.com/golang-jwt/jwt/v5 v5.2.2 h1:Rl4B7itRWVtYIHFrSNd7vhTiz9UpLdi6gZhZ3wEeDy8=
|
||||
github.com/golang-jwt/jwt/v5 v5.2.2/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/glog v1.2.4 h1:CNNw5U8lSiiBk7druxtSHHTsRWcxKoac6kZKm2peBBc=
|
||||
github.com/golang/glog v1.2.4/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w=
|
||||
|
||||
@@ -6,7 +6,6 @@ import (
|
||||
"os"
|
||||
"os/exec"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
@@ -52,61 +51,59 @@ func extractPatchAndRC(tag string) (string, string, error) {
|
||||
return patch, rc, nil
|
||||
}
|
||||
|
||||
func findPreviousTag(proposedTag string, tags []string) (string, error) {
|
||||
var previousTag string
|
||||
proposedMajor := semver.Major(proposedTag)
|
||||
proposedMinor := semver.MajorMinor(proposedTag)
|
||||
|
||||
proposedPatch, proposedRC, err := extractPatchAndRC(proposedTag)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// If the current tag is a .0 patch release or a 1 release candidate, adjust to the previous minor release series.
|
||||
if (proposedPatch == "0" && proposedRC == "0") || proposedRC == "1" {
|
||||
proposedMinorInt, err := strconv.Atoi(strings.TrimPrefix(proposedMinor, proposedMajor+"."))
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("invalid minor version: %v", err)
|
||||
}
|
||||
if proposedMinorInt > 0 {
|
||||
proposedMinor = fmt.Sprintf("%s.%d", proposedMajor, proposedMinorInt-1)
|
||||
}
|
||||
}
|
||||
|
||||
func removeInvalidTags(tags []string) []string {
|
||||
var validTags []string
|
||||
for _, tag := range tags {
|
||||
if tag == proposedTag {
|
||||
continue
|
||||
}
|
||||
tagMajor := semver.Major(tag)
|
||||
tagMinor := semver.MajorMinor(tag)
|
||||
tagPatch, tagRC, err := extractPatchAndRC(tag)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
// Only bother considering tags with the same major and minor version.
|
||||
if tagMajor == proposedMajor && tagMinor == proposedMinor {
|
||||
// If it's a non-RC release...
|
||||
if proposedRC == "0" {
|
||||
// Only consider non-RC tags.
|
||||
if tagRC == "0" {
|
||||
if semver.Compare(tag, previousTag) > 0 {
|
||||
previousTag = tag
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if tagRC != "0" && tagPatch == proposedPatch {
|
||||
if semver.Compare(tag, previousTag) > 0 {
|
||||
previousTag = tag
|
||||
}
|
||||
} else if tagRC == "0" {
|
||||
if semver.Compare(tag, previousTag) > 0 {
|
||||
previousTag = tag
|
||||
}
|
||||
}
|
||||
}
|
||||
if _, _, err := extractPatchAndRC(tag); err == nil {
|
||||
validTags = append(validTags, tag)
|
||||
}
|
||||
}
|
||||
return validTags
|
||||
}
|
||||
|
||||
func removeNewerOrEqualTags(proposedTag string, tags []string) []string {
|
||||
var validTags []string
|
||||
for _, tag := range tags {
|
||||
if semver.Compare(tag, proposedTag) < 0 {
|
||||
validTags = append(validTags, tag)
|
||||
}
|
||||
}
|
||||
return validTags
|
||||
}
|
||||
|
||||
func removeTagsFromSameMinorSeries(proposedTag string, tags []string) []string {
|
||||
var validTags []string
|
||||
proposedMinor := semver.MajorMinor(proposedTag)
|
||||
for _, tag := range tags {
|
||||
if semver.MajorMinor(tag) != proposedMinor {
|
||||
validTags = append(validTags, tag)
|
||||
}
|
||||
}
|
||||
return validTags
|
||||
}
|
||||
|
||||
func getMostRecentTag(tags []string) string {
|
||||
var mostRecentTag string
|
||||
for _, tag := range tags {
|
||||
if mostRecentTag == "" || semver.Compare(tag, mostRecentTag) > 0 {
|
||||
mostRecentTag = tag
|
||||
}
|
||||
}
|
||||
return mostRecentTag
|
||||
}
|
||||
|
||||
func findPreviousTag(proposedTag string, tags []string) (string, error) {
|
||||
tags = removeInvalidTags(tags)
|
||||
tags = removeNewerOrEqualTags(proposedTag, tags)
|
||||
|
||||
proposedPatch, proposedRC, _ := extractPatchAndRC(proposedTag) // Ignore the error, we already filtered out invalid tags.
|
||||
if proposedRC == "0" && proposedPatch == "0" {
|
||||
// If we're cutting the first patch of a new minor release series, don't consider tags in the same minor release
|
||||
// series. We want to compare to the latest tag in the previous minor release series.
|
||||
tags = removeTagsFromSameMinorSeries(proposedTag, tags)
|
||||
}
|
||||
|
||||
previousTag := getMostRecentTag(tags)
|
||||
if previousTag == "" {
|
||||
return "", fmt.Errorf("no matching tag found for tags: " + strings.Join(tags, ", "))
|
||||
}
|
||||
|
||||
@@ -76,6 +76,13 @@ func TestFindPreviousTagRules(t *testing.T) {
|
||||
{"Rule 3: 1 release candidate", "v2.14.0-rc1", "v2.13.0-rc3", false},
|
||||
// Rule 4: If we're releasing a non-1 release candidate, get the most recent rc tag on the current minor release series.
|
||||
{"Rule 4: non-1 release candidate", "v2.13.0-rc4", "v2.13.0-rc3", false},
|
||||
// Rule 5: If we're releasing a major version RC, get the most recent tag on the previous major release series.
|
||||
{"Rule 5: major version RC", "v3.0.0-rc1", "v2.13.0-rc3", false},
|
||||
// Rule 6: If we're releasing a major version, get the most recent tag on the previous major release series,
|
||||
// even if it's an RC.
|
||||
{"Rule 6: major version", "v3.0.0", "v2.13.0-rc3", false},
|
||||
// Rule 7: If the proposed tag already exists, don't return it.
|
||||
{"Rule 7: proposed tag already exists", "v2.12.5", "v2.12.4", false},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
|
||||
@@ -7,8 +7,9 @@ argocd_minor_version=$(git rev-parse --abbrev-ref HEAD | sed 's/release-//')
|
||||
argocd_major_version_num=$(echo "$argocd_minor_version" | sed -E 's/\.[0-9]+//')
|
||||
argocd_minor_version_num=$(echo "$argocd_minor_version" | sed -E 's/[0-9]+\.//')
|
||||
|
||||
for n in 0 1 2; do
|
||||
minor_version_num=$((argocd_minor_version_num - n))
|
||||
minor_version_decrement=0
|
||||
for _ in {1..3}; do
|
||||
minor_version_num=$((argocd_minor_version_num - minor_version_decrement))
|
||||
minor_version="${argocd_major_version_num}.${minor_version_num}"
|
||||
git checkout "release-$minor_version" > /dev/null || exit 1
|
||||
|
||||
@@ -19,9 +20,22 @@ for n in 0 1 2; do
|
||||
jq --arg minor_version "$minor_version" --raw-input --slurp --raw-output \
|
||||
'split("\n")[:-1] | map(sub("\\.[0-9]+$"; "")) | join(", ") | "| \($minor_version) | \(.) |"')
|
||||
out+="$line\n"
|
||||
|
||||
minor_version_decrement=$((minor_version_decrement + 1))
|
||||
|
||||
# If we're at minor version 0, there's no further version back in this series. Instead, move to the latest version in
|
||||
# the previous major release series.
|
||||
if [ "$argocd_minor_version_num" -eq 0 ]; then
|
||||
argocd_major_version_num=$((argocd_major_version_num - 1))
|
||||
# Get the latest minor version in the previous series.
|
||||
argocd_minor_version_num=$(git tag -l "v$argocd_major_version_num.*" | sort -V | tail -n 1 | sed -E 's/\.[0-9]+$//' | sed -E 's/^v[0-9]+\.//')
|
||||
|
||||
# Don't decrement the minor version, since we're switching to the previous major release series. We want the latest
|
||||
# minor version in that series.
|
||||
minor_version_decrement=0
|
||||
fi
|
||||
done
|
||||
|
||||
git checkout "release-$argocd_minor_version"
|
||||
|
||||
|
||||
printf "$out" > docs/operator-manual/tested-kubernetes-versions.md
|
||||
|
||||
@@ -70,10 +70,6 @@ data:
|
||||
- Endpoints
|
||||
- EndpointSlice
|
||||
### Internal Kubernetes resources excluded reduce the number of watched events
|
||||
- apiGroups:
|
||||
- apiregistration.k8s.io
|
||||
kinds:
|
||||
- APIService
|
||||
- apiGroups:
|
||||
- coordination.k8s.io
|
||||
kinds:
|
||||
|
||||
@@ -5,7 +5,7 @@ kind: Kustomization
|
||||
images:
|
||||
- name: quay.io/argoproj/argocd
|
||||
newName: quay.io/argoproj/argocd
|
||||
newTag: latest
|
||||
newTag: v3.0.1
|
||||
resources:
|
||||
- ./application-controller
|
||||
- ./dex
|
||||
|
||||
14
manifests/core-install-with-hydrator.yaml
generated
14
manifests/core-install-with-hydrator.yaml
generated
@@ -24217,10 +24217,6 @@ data:
|
||||
- Endpoints
|
||||
- EndpointSlice
|
||||
### Internal Kubernetes resources excluded reduce the number of watched events
|
||||
- apiGroups:
|
||||
- apiregistration.k8s.io
|
||||
kinds:
|
||||
- APIService
|
||||
- apiGroups:
|
||||
- coordination.k8s.io
|
||||
kinds:
|
||||
@@ -24613,7 +24609,7 @@ spec:
|
||||
key: applicationsetcontroller.requeue.after
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.1
|
||||
imagePullPolicy: Always
|
||||
name: argocd-applicationset-controller
|
||||
ports:
|
||||
@@ -24889,7 +24885,7 @@ spec:
|
||||
- argocd
|
||||
- admin
|
||||
- redis-initial-password
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.1
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: secret-init
|
||||
securityContext:
|
||||
@@ -25162,7 +25158,7 @@ spec:
|
||||
value: /helm-working-dir
|
||||
- name: HELM_DATA_HOME
|
||||
value: /helm-working-dir
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.1
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
failureThreshold: 3
|
||||
@@ -25214,7 +25210,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /var/run/argocd/argocd-cmp-server
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.1
|
||||
name: copyutil
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
@@ -25544,7 +25540,7 @@ spec:
|
||||
optional: true
|
||||
- name: KUBECACHEDIR
|
||||
value: /tmp/kubecache
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.1
|
||||
imagePullPolicy: Always
|
||||
name: argocd-application-controller
|
||||
ports:
|
||||
|
||||
14
manifests/core-install.yaml
generated
14
manifests/core-install.yaml
generated
@@ -24208,10 +24208,6 @@ data:
|
||||
- Endpoints
|
||||
- EndpointSlice
|
||||
### Internal Kubernetes resources excluded reduce the number of watched events
|
||||
- apiGroups:
|
||||
- apiregistration.k8s.io
|
||||
kinds:
|
||||
- APIService
|
||||
- apiGroups:
|
||||
- coordination.k8s.io
|
||||
kinds:
|
||||
@@ -24581,7 +24577,7 @@ spec:
|
||||
key: applicationsetcontroller.requeue.after
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.1
|
||||
imagePullPolicy: Always
|
||||
name: argocd-applicationset-controller
|
||||
ports:
|
||||
@@ -24701,7 +24697,7 @@ spec:
|
||||
- argocd
|
||||
- admin
|
||||
- redis-initial-password
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.1
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: secret-init
|
||||
securityContext:
|
||||
@@ -24974,7 +24970,7 @@ spec:
|
||||
value: /helm-working-dir
|
||||
- name: HELM_DATA_HOME
|
||||
value: /helm-working-dir
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.1
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
failureThreshold: 3
|
||||
@@ -25026,7 +25022,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /var/run/argocd/argocd-cmp-server
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.1
|
||||
name: copyutil
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
@@ -25356,7 +25352,7 @@ spec:
|
||||
optional: true
|
||||
- name: KUBECACHEDIR
|
||||
value: /tmp/kubecache
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.1
|
||||
imagePullPolicy: Always
|
||||
name: argocd-application-controller
|
||||
ports:
|
||||
|
||||
@@ -12,4 +12,4 @@ resources:
|
||||
images:
|
||||
- name: quay.io/argoproj/argocd
|
||||
newName: quay.io/argoproj/argocd
|
||||
newTag: latest
|
||||
newTag: v3.0.1
|
||||
|
||||
@@ -12,7 +12,7 @@ patches:
|
||||
images:
|
||||
- name: quay.io/argoproj/argocd
|
||||
newName: quay.io/argoproj/argocd
|
||||
newTag: latest
|
||||
newTag: v3.0.1
|
||||
resources:
|
||||
- ../../base/application-controller
|
||||
- ../../base/applicationset-controller
|
||||
|
||||
@@ -1101,7 +1101,7 @@ spec:
|
||||
fsGroup: 99
|
||||
runAsNonRoot: true
|
||||
runAsUser: 99
|
||||
automountServiceAccountToken: false
|
||||
automountServiceAccountToken: true
|
||||
nodeSelector:
|
||||
{}
|
||||
tolerations:
|
||||
|
||||
@@ -21,6 +21,8 @@ redis-ha:
|
||||
checkInterval: 3s
|
||||
metrics:
|
||||
enabled: true
|
||||
serviceAccount:
|
||||
automountToken: true
|
||||
image:
|
||||
tag: 7.2.7-alpine
|
||||
sentinel:
|
||||
|
||||
22
manifests/ha/install-with-hydrator.yaml
generated
22
manifests/ha/install-with-hydrator.yaml
generated
@@ -24626,10 +24626,6 @@ data:
|
||||
- Endpoints
|
||||
- EndpointSlice
|
||||
### Internal Kubernetes resources excluded reduce the number of watched events
|
||||
- apiGroups:
|
||||
- apiregistration.k8s.io
|
||||
kinds:
|
||||
- APIService
|
||||
- apiGroups:
|
||||
- coordination.k8s.io
|
||||
kinds:
|
||||
@@ -25978,7 +25974,7 @@ spec:
|
||||
key: applicationsetcontroller.requeue.after
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.1
|
||||
imagePullPolicy: Always
|
||||
name: argocd-applicationset-controller
|
||||
ports:
|
||||
@@ -26277,7 +26273,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /shared/argocd-dex
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.1
|
||||
imagePullPolicy: Always
|
||||
name: copyutil
|
||||
securityContext:
|
||||
@@ -26373,7 +26369,7 @@ spec:
|
||||
key: notificationscontroller.repo.server.plaintext
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.1
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
tcpSocket:
|
||||
@@ -26448,7 +26444,7 @@ spec:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: argocd-redis-ha-haproxy
|
||||
topologyKey: kubernetes.io/hostname
|
||||
automountServiceAccountToken: false
|
||||
automountServiceAccountToken: true
|
||||
containers:
|
||||
- env:
|
||||
- name: AUTH
|
||||
@@ -26497,7 +26493,7 @@ spec:
|
||||
- argocd
|
||||
- admin
|
||||
- redis-initial-password
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.1
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: secret-init
|
||||
securityContext:
|
||||
@@ -26796,7 +26792,7 @@ spec:
|
||||
value: /helm-working-dir
|
||||
- name: HELM_DATA_HOME
|
||||
value: /helm-working-dir
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.1
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
failureThreshold: 3
|
||||
@@ -26848,7 +26844,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /var/run/argocd/argocd-cmp-server
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.1
|
||||
name: copyutil
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
@@ -27222,7 +27218,7 @@ spec:
|
||||
key: server.sync.replace.allowed
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.1
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
@@ -27588,7 +27584,7 @@ spec:
|
||||
optional: true
|
||||
- name: KUBECACHEDIR
|
||||
value: /tmp/kubecache
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.1
|
||||
imagePullPolicy: Always
|
||||
name: argocd-application-controller
|
||||
ports:
|
||||
|
||||
22
manifests/ha/install.yaml
generated
22
manifests/ha/install.yaml
generated
@@ -24617,10 +24617,6 @@ data:
|
||||
- Endpoints
|
||||
- EndpointSlice
|
||||
### Internal Kubernetes resources excluded reduce the number of watched events
|
||||
- apiGroups:
|
||||
- apiregistration.k8s.io
|
||||
kinds:
|
||||
- APIService
|
||||
- apiGroups:
|
||||
- coordination.k8s.io
|
||||
kinds:
|
||||
@@ -25948,7 +25944,7 @@ spec:
|
||||
key: applicationsetcontroller.requeue.after
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.1
|
||||
imagePullPolicy: Always
|
||||
name: argocd-applicationset-controller
|
||||
ports:
|
||||
@@ -26091,7 +26087,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /shared/argocd-dex
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.1
|
||||
imagePullPolicy: Always
|
||||
name: copyutil
|
||||
securityContext:
|
||||
@@ -26187,7 +26183,7 @@ spec:
|
||||
key: notificationscontroller.repo.server.plaintext
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.1
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
tcpSocket:
|
||||
@@ -26262,7 +26258,7 @@ spec:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: argocd-redis-ha-haproxy
|
||||
topologyKey: kubernetes.io/hostname
|
||||
automountServiceAccountToken: false
|
||||
automountServiceAccountToken: true
|
||||
containers:
|
||||
- env:
|
||||
- name: AUTH
|
||||
@@ -26311,7 +26307,7 @@ spec:
|
||||
- argocd
|
||||
- admin
|
||||
- redis-initial-password
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.1
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: secret-init
|
||||
securityContext:
|
||||
@@ -26610,7 +26606,7 @@ spec:
|
||||
value: /helm-working-dir
|
||||
- name: HELM_DATA_HOME
|
||||
value: /helm-working-dir
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.1
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
failureThreshold: 3
|
||||
@@ -26662,7 +26658,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /var/run/argocd/argocd-cmp-server
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.1
|
||||
name: copyutil
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
@@ -27036,7 +27032,7 @@ spec:
|
||||
key: server.sync.replace.allowed
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.1
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
@@ -27402,7 +27398,7 @@ spec:
|
||||
optional: true
|
||||
- name: KUBECACHEDIR
|
||||
value: /tmp/kubecache
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.1
|
||||
imagePullPolicy: Always
|
||||
name: argocd-application-controller
|
||||
ports:
|
||||
|
||||
22
manifests/ha/namespace-install-with-hydrator.yaml
generated
22
manifests/ha/namespace-install-with-hydrator.yaml
generated
@@ -513,10 +513,6 @@ data:
|
||||
- Endpoints
|
||||
- EndpointSlice
|
||||
### Internal Kubernetes resources excluded reduce the number of watched events
|
||||
- apiGroups:
|
||||
- apiregistration.k8s.io
|
||||
kinds:
|
||||
- APIService
|
||||
- apiGroups:
|
||||
- coordination.k8s.io
|
||||
kinds:
|
||||
@@ -1865,7 +1861,7 @@ spec:
|
||||
key: applicationsetcontroller.requeue.after
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.1
|
||||
imagePullPolicy: Always
|
||||
name: argocd-applicationset-controller
|
||||
ports:
|
||||
@@ -2164,7 +2160,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /shared/argocd-dex
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.1
|
||||
imagePullPolicy: Always
|
||||
name: copyutil
|
||||
securityContext:
|
||||
@@ -2260,7 +2256,7 @@ spec:
|
||||
key: notificationscontroller.repo.server.plaintext
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.1
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
tcpSocket:
|
||||
@@ -2335,7 +2331,7 @@ spec:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: argocd-redis-ha-haproxy
|
||||
topologyKey: kubernetes.io/hostname
|
||||
automountServiceAccountToken: false
|
||||
automountServiceAccountToken: true
|
||||
containers:
|
||||
- env:
|
||||
- name: AUTH
|
||||
@@ -2384,7 +2380,7 @@ spec:
|
||||
- argocd
|
||||
- admin
|
||||
- redis-initial-password
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.1
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: secret-init
|
||||
securityContext:
|
||||
@@ -2683,7 +2679,7 @@ spec:
|
||||
value: /helm-working-dir
|
||||
- name: HELM_DATA_HOME
|
||||
value: /helm-working-dir
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.1
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
failureThreshold: 3
|
||||
@@ -2735,7 +2731,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /var/run/argocd/argocd-cmp-server
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.1
|
||||
name: copyutil
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
@@ -3109,7 +3105,7 @@ spec:
|
||||
key: server.sync.replace.allowed
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.1
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
@@ -3475,7 +3471,7 @@ spec:
|
||||
optional: true
|
||||
- name: KUBECACHEDIR
|
||||
value: /tmp/kubecache
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.1
|
||||
imagePullPolicy: Always
|
||||
name: argocd-application-controller
|
||||
ports:
|
||||
|
||||
22
manifests/ha/namespace-install.yaml
generated
22
manifests/ha/namespace-install.yaml
generated
@@ -504,10 +504,6 @@ data:
|
||||
- Endpoints
|
||||
- EndpointSlice
|
||||
### Internal Kubernetes resources excluded reduce the number of watched events
|
||||
- apiGroups:
|
||||
- apiregistration.k8s.io
|
||||
kinds:
|
||||
- APIService
|
||||
- apiGroups:
|
||||
- coordination.k8s.io
|
||||
kinds:
|
||||
@@ -1835,7 +1831,7 @@ spec:
|
||||
key: applicationsetcontroller.requeue.after
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.1
|
||||
imagePullPolicy: Always
|
||||
name: argocd-applicationset-controller
|
||||
ports:
|
||||
@@ -1978,7 +1974,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /shared/argocd-dex
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.1
|
||||
imagePullPolicy: Always
|
||||
name: copyutil
|
||||
securityContext:
|
||||
@@ -2074,7 +2070,7 @@ spec:
|
||||
key: notificationscontroller.repo.server.plaintext
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.1
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
tcpSocket:
|
||||
@@ -2149,7 +2145,7 @@ spec:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: argocd-redis-ha-haproxy
|
||||
topologyKey: kubernetes.io/hostname
|
||||
automountServiceAccountToken: false
|
||||
automountServiceAccountToken: true
|
||||
containers:
|
||||
- env:
|
||||
- name: AUTH
|
||||
@@ -2198,7 +2194,7 @@ spec:
|
||||
- argocd
|
||||
- admin
|
||||
- redis-initial-password
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.1
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: secret-init
|
||||
securityContext:
|
||||
@@ -2497,7 +2493,7 @@ spec:
|
||||
value: /helm-working-dir
|
||||
- name: HELM_DATA_HOME
|
||||
value: /helm-working-dir
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.1
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
failureThreshold: 3
|
||||
@@ -2549,7 +2545,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /var/run/argocd/argocd-cmp-server
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.1
|
||||
name: copyutil
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
@@ -2923,7 +2919,7 @@ spec:
|
||||
key: server.sync.replace.allowed
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.1
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
@@ -3289,7 +3285,7 @@ spec:
|
||||
optional: true
|
||||
- name: KUBECACHEDIR
|
||||
value: /tmp/kubecache
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.1
|
||||
imagePullPolicy: Always
|
||||
name: argocd-application-controller
|
||||
ports:
|
||||
|
||||
20
manifests/install-with-hydrator.yaml
generated
20
manifests/install-with-hydrator.yaml
generated
@@ -24577,10 +24577,6 @@ data:
|
||||
- Endpoints
|
||||
- EndpointSlice
|
||||
### Internal Kubernetes resources excluded reduce the number of watched events
|
||||
- apiGroups:
|
||||
- apiregistration.k8s.io
|
||||
kinds:
|
||||
- APIService
|
||||
- apiGroups:
|
||||
- coordination.k8s.io
|
||||
kinds:
|
||||
@@ -25073,7 +25069,7 @@ spec:
|
||||
key: applicationsetcontroller.requeue.after
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.1
|
||||
imagePullPolicy: Always
|
||||
name: argocd-applicationset-controller
|
||||
ports:
|
||||
@@ -25372,7 +25368,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /shared/argocd-dex
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.1
|
||||
imagePullPolicy: Always
|
||||
name: copyutil
|
||||
securityContext:
|
||||
@@ -25468,7 +25464,7 @@ spec:
|
||||
key: notificationscontroller.repo.server.plaintext
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.1
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
tcpSocket:
|
||||
@@ -25570,7 +25566,7 @@ spec:
|
||||
- argocd
|
||||
- admin
|
||||
- redis-initial-password
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.1
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: secret-init
|
||||
securityContext:
|
||||
@@ -25843,7 +25839,7 @@ spec:
|
||||
value: /helm-working-dir
|
||||
- name: HELM_DATA_HOME
|
||||
value: /helm-working-dir
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.1
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
failureThreshold: 3
|
||||
@@ -25895,7 +25891,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /var/run/argocd/argocd-cmp-server
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.1
|
||||
name: copyutil
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
@@ -26267,7 +26263,7 @@ spec:
|
||||
key: server.sync.replace.allowed
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.1
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
@@ -26633,7 +26629,7 @@ spec:
|
||||
optional: true
|
||||
- name: KUBECACHEDIR
|
||||
value: /tmp/kubecache
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.1
|
||||
imagePullPolicy: Always
|
||||
name: argocd-application-controller
|
||||
ports:
|
||||
|
||||
20
manifests/install.yaml
generated
20
manifests/install.yaml
generated
@@ -24568,10 +24568,6 @@ data:
|
||||
- Endpoints
|
||||
- EndpointSlice
|
||||
### Internal Kubernetes resources excluded reduce the number of watched events
|
||||
- apiGroups:
|
||||
- apiregistration.k8s.io
|
||||
kinds:
|
||||
- APIService
|
||||
- apiGroups:
|
||||
- coordination.k8s.io
|
||||
kinds:
|
||||
@@ -25041,7 +25037,7 @@ spec:
|
||||
key: applicationsetcontroller.requeue.after
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.1
|
||||
imagePullPolicy: Always
|
||||
name: argocd-applicationset-controller
|
||||
ports:
|
||||
@@ -25184,7 +25180,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /shared/argocd-dex
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.1
|
||||
imagePullPolicy: Always
|
||||
name: copyutil
|
||||
securityContext:
|
||||
@@ -25280,7 +25276,7 @@ spec:
|
||||
key: notificationscontroller.repo.server.plaintext
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.1
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
tcpSocket:
|
||||
@@ -25382,7 +25378,7 @@ spec:
|
||||
- argocd
|
||||
- admin
|
||||
- redis-initial-password
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.1
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: secret-init
|
||||
securityContext:
|
||||
@@ -25655,7 +25651,7 @@ spec:
|
||||
value: /helm-working-dir
|
||||
- name: HELM_DATA_HOME
|
||||
value: /helm-working-dir
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.1
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
failureThreshold: 3
|
||||
@@ -25707,7 +25703,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /var/run/argocd/argocd-cmp-server
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.1
|
||||
name: copyutil
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
@@ -26079,7 +26075,7 @@ spec:
|
||||
key: server.sync.replace.allowed
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.1
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
@@ -26445,7 +26441,7 @@ spec:
|
||||
optional: true
|
||||
- name: KUBECACHEDIR
|
||||
value: /tmp/kubecache
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.1
|
||||
imagePullPolicy: Always
|
||||
name: argocd-application-controller
|
||||
ports:
|
||||
|
||||
20
manifests/namespace-install-with-hydrator.yaml
generated
20
manifests/namespace-install-with-hydrator.yaml
generated
@@ -464,10 +464,6 @@ data:
|
||||
- Endpoints
|
||||
- EndpointSlice
|
||||
### Internal Kubernetes resources excluded reduce the number of watched events
|
||||
- apiGroups:
|
||||
- apiregistration.k8s.io
|
||||
kinds:
|
||||
- APIService
|
||||
- apiGroups:
|
||||
- coordination.k8s.io
|
||||
kinds:
|
||||
@@ -960,7 +956,7 @@ spec:
|
||||
key: applicationsetcontroller.requeue.after
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.1
|
||||
imagePullPolicy: Always
|
||||
name: argocd-applicationset-controller
|
||||
ports:
|
||||
@@ -1259,7 +1255,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /shared/argocd-dex
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.1
|
||||
imagePullPolicy: Always
|
||||
name: copyutil
|
||||
securityContext:
|
||||
@@ -1355,7 +1351,7 @@ spec:
|
||||
key: notificationscontroller.repo.server.plaintext
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.1
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
tcpSocket:
|
||||
@@ -1457,7 +1453,7 @@ spec:
|
||||
- argocd
|
||||
- admin
|
||||
- redis-initial-password
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.1
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: secret-init
|
||||
securityContext:
|
||||
@@ -1730,7 +1726,7 @@ spec:
|
||||
value: /helm-working-dir
|
||||
- name: HELM_DATA_HOME
|
||||
value: /helm-working-dir
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.1
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
failureThreshold: 3
|
||||
@@ -1782,7 +1778,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /var/run/argocd/argocd-cmp-server
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.1
|
||||
name: copyutil
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
@@ -2154,7 +2150,7 @@ spec:
|
||||
key: server.sync.replace.allowed
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.1
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
@@ -2520,7 +2516,7 @@ spec:
|
||||
optional: true
|
||||
- name: KUBECACHEDIR
|
||||
value: /tmp/kubecache
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.1
|
||||
imagePullPolicy: Always
|
||||
name: argocd-application-controller
|
||||
ports:
|
||||
|
||||
20
manifests/namespace-install.yaml
generated
20
manifests/namespace-install.yaml
generated
@@ -455,10 +455,6 @@ data:
|
||||
- Endpoints
|
||||
- EndpointSlice
|
||||
### Internal Kubernetes resources excluded reduce the number of watched events
|
||||
- apiGroups:
|
||||
- apiregistration.k8s.io
|
||||
kinds:
|
||||
- APIService
|
||||
- apiGroups:
|
||||
- coordination.k8s.io
|
||||
kinds:
|
||||
@@ -928,7 +924,7 @@ spec:
|
||||
key: applicationsetcontroller.requeue.after
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.1
|
||||
imagePullPolicy: Always
|
||||
name: argocd-applicationset-controller
|
||||
ports:
|
||||
@@ -1071,7 +1067,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /shared/argocd-dex
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.1
|
||||
imagePullPolicy: Always
|
||||
name: copyutil
|
||||
securityContext:
|
||||
@@ -1167,7 +1163,7 @@ spec:
|
||||
key: notificationscontroller.repo.server.plaintext
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.1
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
tcpSocket:
|
||||
@@ -1269,7 +1265,7 @@ spec:
|
||||
- argocd
|
||||
- admin
|
||||
- redis-initial-password
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.1
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: secret-init
|
||||
securityContext:
|
||||
@@ -1542,7 +1538,7 @@ spec:
|
||||
value: /helm-working-dir
|
||||
- name: HELM_DATA_HOME
|
||||
value: /helm-working-dir
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.1
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
failureThreshold: 3
|
||||
@@ -1594,7 +1590,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /var/run/argocd/argocd-cmp-server
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.1
|
||||
name: copyutil
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
@@ -1966,7 +1962,7 @@ spec:
|
||||
key: server.sync.replace.allowed
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.1
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
@@ -2332,7 +2328,7 @@ spec:
|
||||
optional: true
|
||||
- name: KUBECACHEDIR
|
||||
value: /tmp/kubecache
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.0.1
|
||||
imagePullPolicy: Always
|
||||
name: argocd-application-controller
|
||||
ports:
|
||||
|
||||
@@ -130,6 +130,7 @@ nav:
|
||||
- operator-manual/server-commands/additional-configuration-method.md
|
||||
- Upgrading:
|
||||
- operator-manual/upgrading/overview.md
|
||||
- operator-manual/upgrading/2.14-3.0.md
|
||||
- operator-manual/upgrading/2.13-2.14.md
|
||||
- operator-manual/upgrading/2.12-2.13.md
|
||||
- operator-manual/upgrading/2.11-2.12.md
|
||||
|
||||
@@ -338,7 +338,7 @@ func (s *Service) runRepoOperation(
|
||||
|
||||
if source.IsHelm() {
|
||||
if settings.noCache {
|
||||
err = helmClient.CleanChartCache(source.Chart, revision, repo.Project)
|
||||
err = helmClient.CleanChartCache(source.Chart, revision)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -347,7 +347,7 @@ func (s *Service) runRepoOperation(
|
||||
if source.Helm != nil {
|
||||
helmPassCredentials = source.Helm.PassCredentials
|
||||
}
|
||||
chartPath, closer, err := helmClient.ExtractChart(source.Chart, revision, repo.Project, helmPassCredentials, s.initConstants.HelmManifestMaxExtractedSize, s.initConstants.DisableHelmManifestMaxExtractedSize)
|
||||
chartPath, closer, err := helmClient.ExtractChart(source.Chart, revision, helmPassCredentials, s.initConstants.HelmManifestMaxExtractedSize, s.initConstants.DisableHelmManifestMaxExtractedSize)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -1155,7 +1155,7 @@ func helmTemplate(appPath string, repoRoot string, env *v1alpha1.Env, q *apiclie
|
||||
referencedSource := getReferencedSource(p.Path, q.RefSources)
|
||||
if referencedSource != nil {
|
||||
// If the $-prefixed path appears to reference another source, do env substitution _after_ resolving the source
|
||||
resolvedPath, err = getResolvedRefValueFile(p.Path, env, q.GetValuesFileSchemes(), referencedSource.Repo.Repo, gitRepoPaths, referencedSource.Repo.Project)
|
||||
resolvedPath, err = getResolvedRefValueFile(p.Path, env, q.GetValuesFileSchemes(), referencedSource.Repo.Repo, gitRepoPaths)
|
||||
if err != nil {
|
||||
return nil, "", fmt.Errorf("error resolving set-file path: %w", err)
|
||||
}
|
||||
@@ -1276,7 +1276,7 @@ func getResolvedValueFiles(
|
||||
referencedSource := getReferencedSource(rawValueFile, refSources)
|
||||
if referencedSource != nil {
|
||||
// If the $-prefixed path appears to reference another source, do env substitution _after_ resolving that source.
|
||||
resolvedPath, err = getResolvedRefValueFile(rawValueFile, env, allowedValueFilesSchemas, referencedSource.Repo.Repo, gitRepoPaths, referencedSource.Repo.Project)
|
||||
resolvedPath, err = getResolvedRefValueFile(rawValueFile, env, allowedValueFilesSchemas, referencedSource.Repo.Repo, gitRepoPaths)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error resolving value file path: %w", err)
|
||||
}
|
||||
@@ -1309,15 +1309,9 @@ func getResolvedRefValueFile(
|
||||
allowedValueFilesSchemas []string,
|
||||
refSourceRepo string,
|
||||
gitRepoPaths io.TempPaths,
|
||||
project string,
|
||||
) (pathutil.ResolvedFilePath, error) {
|
||||
pathStrings := strings.Split(rawValueFile, "/")
|
||||
|
||||
keyData, err := json.Marshal(map[string]string{"url": git.NormalizeGitURL(refSourceRepo), "project": project})
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
repoPath := gitRepoPaths.GetPathIfExists(string(keyData))
|
||||
repoPath := gitRepoPaths.GetPathIfExists(git.NormalizeGitURL(refSourceRepo))
|
||||
if repoPath == "" {
|
||||
return "", fmt.Errorf("failed to find repo %q", refSourceRepo)
|
||||
}
|
||||
@@ -2353,7 +2347,7 @@ func (s *Service) GetRevisionChartDetails(_ context.Context, q *apiclient.RepoSe
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("helm client error: %w", err)
|
||||
}
|
||||
chartPath, closer, err := helmClient.ExtractChart(q.Name, revision, q.Repo.Project, false, s.initConstants.HelmManifestMaxExtractedSize, s.initConstants.DisableHelmManifestMaxExtractedSize)
|
||||
chartPath, closer, err := helmClient.ExtractChart(q.Name, revision, false, s.initConstants.HelmManifestMaxExtractedSize, s.initConstants.DisableHelmManifestMaxExtractedSize)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error extracting chart: %w", err)
|
||||
}
|
||||
@@ -2383,11 +2377,7 @@ func fileParameters(q *apiclient.RepoServerAppDetailsQuery) []v1alpha1.HelmFileP
|
||||
}
|
||||
|
||||
func (s *Service) newClient(repo *v1alpha1.Repository, opts ...git.ClientOpts) (git.Client, error) {
|
||||
keyData, err := json.Marshal(map[string]string{"url": git.NormalizeGitURL(repo.Repo), "project": repo.Project})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
repoPath, err := s.gitRepoPaths.GetPath(string(keyData))
|
||||
repoPath, err := s.gitRepoPaths.GetPath(git.NormalizeGitURL(repo.Repo))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -126,10 +126,10 @@ func newServiceWithMocks(t *testing.T, root string, signed bool) (*Service, *git
|
||||
chart: {{Version: "1.0.0"}, {Version: version}},
|
||||
oobChart: {{Version: "1.0.0"}, {Version: version}},
|
||||
}}, nil)
|
||||
helmClient.On("ExtractChart", chart, version, "", false, int64(0), false).Return("./testdata/my-chart", io.NopCloser, nil)
|
||||
helmClient.On("ExtractChart", oobChart, version, "", false, int64(0), false).Return("./testdata2/out-of-bounds-chart", io.NopCloser, nil)
|
||||
helmClient.On("CleanChartCache", chart, version, "").Return(nil)
|
||||
helmClient.On("CleanChartCache", oobChart, version, "").Return(nil)
|
||||
helmClient.On("ExtractChart", chart, version, false, int64(0), false).Return("./testdata/my-chart", io.NopCloser, nil)
|
||||
helmClient.On("ExtractChart", oobChart, version, false, int64(0), false).Return("./testdata2/out-of-bounds-chart", io.NopCloser, nil)
|
||||
helmClient.On("CleanChartCache", chart, version).Return(nil)
|
||||
helmClient.On("CleanChartCache", oobChart, version).Return(nil)
|
||||
helmClient.On("DependencyBuild").Return(nil)
|
||||
|
||||
paths.On("Add", mock.Anything, mock.Anything).Return(root, nil)
|
||||
@@ -3270,8 +3270,7 @@ func Test_getResolvedValueFiles(t *testing.T) {
|
||||
tempDir := t.TempDir()
|
||||
paths := io.NewRandomizedTempPaths(tempDir)
|
||||
|
||||
key, _ := json.Marshal(map[string]string{"url": git.NormalizeGitURL("https://github.com/org/repo1"), "project": ""})
|
||||
paths.Add(string(key), path.Join(tempDir, "repo1"))
|
||||
paths.Add(git.NormalizeGitURL("https://github.com/org/repo1"), path.Join(tempDir, "repo1"))
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
|
||||
@@ -7,8 +7,18 @@ if obj.status == nil or obj.status.conditions == nil then
|
||||
end
|
||||
|
||||
-- Sort conditions by lastTransitionTime, from old to new.
|
||||
-- Ensure that conditions with nil lastTransitionTime are always sorted after those with non-nil values.
|
||||
table.sort(obj.status.conditions, function(a, b)
|
||||
return a.lastTransitionTime < b.lastTransitionTime
|
||||
-- Nil values are considered "less than" non-nil values.
|
||||
-- This means that conditions with nil lastTransitionTime will be sorted to the end.
|
||||
if a.lastTransitionTime == nil then
|
||||
return false
|
||||
elseif b.lastTransitionTime == nil then
|
||||
return true
|
||||
else
|
||||
-- If both have non-nil lastTransitionTime, compare them normally.
|
||||
return a.lastTransitionTime < b.lastTransitionTime
|
||||
end
|
||||
end)
|
||||
|
||||
for _, condition in ipairs(obj.status.conditions) do
|
||||
|
||||
@@ -14,4 +14,8 @@ tests:
|
||||
- healthStatus:
|
||||
status: Degraded
|
||||
message: "Has Errors: Waiting for foo/keycloak-1 due to CrashLoopBackOff: back-off 10s"
|
||||
inputPath: testdata/degraded.yaml
|
||||
inputPath: testdata/degraded.yaml
|
||||
- healthStatus:
|
||||
status: Healthy
|
||||
message: ""
|
||||
inputPath: testdata/nil_last_transition_time.yaml
|
||||
13
resource_customizations/k8s.keycloak.org/Keycloak/testdata/nil_last_transition_time.yaml
vendored
Normal file
13
resource_customizations/k8s.keycloak.org/Keycloak/testdata/nil_last_transition_time.yaml
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
apiVersion: k8s.keycloak.org/v1alpha1
|
||||
kind: Keycloak
|
||||
metadata:
|
||||
name: keycloak-23
|
||||
namespace: keycloak
|
||||
status:
|
||||
conditions:
|
||||
- type: Ready
|
||||
status: "True"
|
||||
lastTransitionTime: "2025-05-06T12:00:00Z" # Non-nil lastTransitionTime
|
||||
- type: HasErrors
|
||||
status: "False"
|
||||
lastTransitionTime: null # Nil lastTransitionTime
|
||||
@@ -232,3 +232,41 @@ func TestGetRepoCLIOutput(t *testing.T) {
|
||||
git https://github.com/argoproj/argo-cd.git false false false false Successful argo-project`, output)
|
||||
})
|
||||
}
|
||||
|
||||
func TestCreateRepoWithSameURLInTwoProjects(t *testing.T) {
|
||||
projectFixture.Given(t).
|
||||
When().
|
||||
Name("project-one").
|
||||
Create().
|
||||
Then()
|
||||
|
||||
projectFixture.Given(t).
|
||||
When().
|
||||
Name("project-two").
|
||||
Create().
|
||||
Then()
|
||||
|
||||
path := "https://github.com/argoproj/argo-cd.git"
|
||||
|
||||
// Create repository in first project
|
||||
repoFixture.GivenWithSameState(t).
|
||||
When().
|
||||
Path(path).
|
||||
Project("project-one").
|
||||
Create().
|
||||
Then().
|
||||
And(func(r *Repository, _ error) {
|
||||
assert.Equal(t, r.Repo, path)
|
||||
})
|
||||
|
||||
// Create repository with same URL in second project
|
||||
repoFixture.GivenWithSameState(t).
|
||||
When().
|
||||
Path(path).
|
||||
Project("project-two").
|
||||
Create().
|
||||
Then().
|
||||
And(func(r *Repository, _ error) {
|
||||
assert.Equal(t, r.Repo, path)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -117,13 +117,15 @@ export const ApplicationStatusPanel = ({application, showDiff, showOperation, sh
|
||||
<div className='application-status-panel__item-name'>{application.status.sourceHydrator.currentOperation.message}</div>
|
||||
)}
|
||||
<div className='application-status-panel__item-name'>
|
||||
<RevisionMetadataPanel
|
||||
appName={application.metadata.name}
|
||||
appNamespace={application.metadata.namespace}
|
||||
type={''}
|
||||
revision={application.status.sourceHydrator.currentOperation.drySHA}
|
||||
versionId={utils.getAppCurrentVersion(application)}
|
||||
/>
|
||||
{application.status.sourceHydrator.currentOperation.drySHA && (
|
||||
<RevisionMetadataPanel
|
||||
appName={application.metadata.name}
|
||||
appNamespace={application.metadata.namespace}
|
||||
type={''}
|
||||
revision={application.status.sourceHydrator.currentOperation.drySHA}
|
||||
versionId={utils.getAppCurrentVersion(application)}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -219,7 +219,7 @@ export class ReposList extends React.Component<
|
||||
tlsClientCertKey: !validURLValues.tlsClientCertKey && validURLValues.tlsClientCertData && 'TLS client cert key is required if TLS client cert is given.',
|
||||
bearerToken:
|
||||
(validURLValues.password && validURLValues.bearerToken && 'Either the password or the bearer token must be set, but not both.') ||
|
||||
(validURLValues.type != 'git' && 'Bearer token is only supported for Git BitBucket Data Center repositories.')
|
||||
(validURLValues.bearerToken && validURLValues.type != 'git' && 'Bearer token is only supported for Git BitBucket Data Center repositories.')
|
||||
};
|
||||
case ConnectionMethod.GITHUBAPP:
|
||||
const githubAppValues = params as NewGitHubAppRepoParams;
|
||||
|
||||
@@ -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/v3/common"
|
||||
@@ -232,6 +233,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 := kube.GetAppInstanceAnnotation(config, common.AnnotationKeyAppInstance)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -204,6 +204,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()
|
||||
|
||||
|
||||
@@ -424,11 +424,14 @@ func (m *nativeGitClient) Fetch(revision string) error {
|
||||
func (m *nativeGitClient) LsFiles(path string, enableNewGitFileGlobbing bool) ([]string, error) {
|
||||
if enableNewGitFileGlobbing {
|
||||
// This is the new way with safer globbing
|
||||
err := os.Chdir(m.root)
|
||||
|
||||
// evaluating the root path for symlinks
|
||||
realRoot, err := filepath.EvalSymlinks(m.root)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
allFiles, err := doublestar.FilepathGlob(path)
|
||||
// searching for the pattern inside the root path
|
||||
allFiles, err := doublestar.FilepathGlob(filepath.Join(realRoot, path))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -442,10 +445,16 @@ func (m *nativeGitClient) LsFiles(path string, enableNewGitFileGlobbing bool) ([
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if strings.HasPrefix(absPath, m.root) {
|
||||
files = append(files, file)
|
||||
|
||||
if strings.HasPrefix(absPath, realRoot) {
|
||||
// removing the repository root prefix from the file path
|
||||
relativeFile, err := filepath.Rel(realRoot, file)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
files = append(files, relativeFile)
|
||||
} else {
|
||||
log.Warnf("Absolute path for %s is outside of repository, removing it", file)
|
||||
log.Warnf("Absolute path for %s is outside of repository, ignoring it", file)
|
||||
}
|
||||
}
|
||||
return files, nil
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@@ -979,6 +980,65 @@ func Test_nativeGitClient_runCredentialedCmd(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func Test_LsFiles_RaceCondition(t *testing.T) {
|
||||
// Create two temporary directories and initialize them as git repositories
|
||||
tempDir1 := t.TempDir()
|
||||
tempDir2 := t.TempDir()
|
||||
|
||||
client1, err := NewClient("file://"+tempDir1, NopCreds{}, true, false, "", "")
|
||||
require.NoError(t, err)
|
||||
client2, err := NewClient("file://"+tempDir2, NopCreds{}, true, false, "", "")
|
||||
require.NoError(t, err)
|
||||
|
||||
err = client1.Init()
|
||||
require.NoError(t, err)
|
||||
err = client2.Init()
|
||||
require.NoError(t, err)
|
||||
|
||||
// Add different files to each repository
|
||||
file1 := filepath.Join(client1.Root(), "file1.txt")
|
||||
err = os.WriteFile(file1, []byte("content1"), 0o644)
|
||||
require.NoError(t, err)
|
||||
err = runCmd(client1.Root(), "git", "add", "file1.txt")
|
||||
require.NoError(t, err)
|
||||
err = runCmd(client1.Root(), "git", "commit", "-m", "Add file1")
|
||||
require.NoError(t, err)
|
||||
|
||||
file2 := filepath.Join(client2.Root(), "file2.txt")
|
||||
err = os.WriteFile(file2, []byte("content2"), 0o644)
|
||||
require.NoError(t, err)
|
||||
err = runCmd(client2.Root(), "git", "add", "file2.txt")
|
||||
require.NoError(t, err)
|
||||
err = runCmd(client2.Root(), "git", "commit", "-m", "Add file2")
|
||||
require.NoError(t, err)
|
||||
|
||||
// Assert that LsFiles returns the correct files when called sequentially
|
||||
files1, err := client1.LsFiles("*", true)
|
||||
require.NoError(t, err)
|
||||
require.Contains(t, files1, "file1.txt")
|
||||
|
||||
files2, err := client2.LsFiles("*", true)
|
||||
require.NoError(t, err)
|
||||
require.Contains(t, files2, "file2.txt")
|
||||
|
||||
// Define a function to call LsFiles multiple times in parallel
|
||||
var wg sync.WaitGroup
|
||||
callLsFiles := func(client Client, expectedFile string) {
|
||||
defer wg.Done()
|
||||
for i := 0; i < 100; i++ {
|
||||
files, err := client.LsFiles("*", true)
|
||||
require.NoError(t, err)
|
||||
require.Contains(t, files, expectedFile)
|
||||
}
|
||||
}
|
||||
|
||||
// Call LsFiles in parallel for both clients
|
||||
wg.Add(2)
|
||||
go callLsFiles(client1, "file1.txt")
|
||||
go callLsFiles(client2, "file2.txt")
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
type mockCreds struct {
|
||||
environ []string
|
||||
environErr bool
|
||||
|
||||
@@ -46,8 +46,8 @@ type indexCache interface {
|
||||
}
|
||||
|
||||
type Client interface {
|
||||
CleanChartCache(chart string, version string, project string) error
|
||||
ExtractChart(chart string, version string, project string, passCredentials bool, manifestMaxExtractedSize int64, disableManifestMaxExtractedSize bool) (string, argoio.Closer, error)
|
||||
CleanChartCache(chart string, version string) error
|
||||
ExtractChart(chart string, version string, passCredentials bool, manifestMaxExtractedSize int64, disableManifestMaxExtractedSize bool) (string, argoio.Closer, error)
|
||||
GetIndex(noCache bool, maxIndexSize int64) (*Index, error)
|
||||
GetTags(chart string, noCache bool) (*TagsList, error)
|
||||
TestHelmOCI() (bool, error)
|
||||
@@ -110,8 +110,8 @@ func fileExist(filePath string) (bool, error) {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (c *nativeHelmChart) CleanChartCache(chart string, version string, project string) error {
|
||||
cachePath, err := c.getCachedChartPath(chart, version, project)
|
||||
func (c *nativeHelmChart) CleanChartCache(chart string, version string) error {
|
||||
cachePath, err := c.getCachedChartPath(chart, version)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error getting cached chart path: %w", err)
|
||||
}
|
||||
@@ -138,7 +138,7 @@ func untarChart(tempDir string, cachedChartPath string, manifestMaxExtractedSize
|
||||
return files.Untgz(tempDir, reader, manifestMaxExtractedSize, false)
|
||||
}
|
||||
|
||||
func (c *nativeHelmChart) ExtractChart(chart string, version string, project string, passCredentials bool, manifestMaxExtractedSize int64, disableManifestMaxExtractedSize bool) (string, argoio.Closer, error) {
|
||||
func (c *nativeHelmChart) ExtractChart(chart string, version string, passCredentials bool, manifestMaxExtractedSize int64, disableManifestMaxExtractedSize bool) (string, argoio.Closer, error) {
|
||||
// always use Helm V3 since we don't have chart content to determine correct Helm version
|
||||
helmCmd, err := NewCmdWithVersion("", c.enableOci, c.proxy, c.noProxy)
|
||||
if err != nil {
|
||||
@@ -152,7 +152,7 @@ func (c *nativeHelmChart) ExtractChart(chart string, version string, project str
|
||||
return "", nil, fmt.Errorf("error creating temporary directory: %w", err)
|
||||
}
|
||||
|
||||
cachedChartPath, err := c.getCachedChartPath(chart, version, project)
|
||||
cachedChartPath, err := c.getCachedChartPath(chart, version)
|
||||
if err != nil {
|
||||
_ = os.RemoveAll(tempDir)
|
||||
return "", nil, fmt.Errorf("error getting cached chart path: %w", err)
|
||||
@@ -387,8 +387,8 @@ func normalizeChartName(chart string) string {
|
||||
return nc
|
||||
}
|
||||
|
||||
func (c *nativeHelmChart) getCachedChartPath(chart string, version string, project string) (string, error) {
|
||||
keyData, err := json.Marshal(map[string]string{"url": c.repoURL, "chart": chart, "version": version, "project": project})
|
||||
func (c *nativeHelmChart) getCachedChartPath(chart string, version string) (string, error) {
|
||||
keyData, err := json.Marshal(map[string]string{"url": c.repoURL, "chart": chart, "version": version})
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("error marshaling cache key data: %w", err)
|
||||
}
|
||||
|
||||
@@ -80,7 +80,7 @@ func TestIndex(t *testing.T) {
|
||||
|
||||
func Test_nativeHelmChart_ExtractChart(t *testing.T) {
|
||||
client := NewClient("https://argoproj.github.io/argo-helm", HelmCreds{}, false, "", "")
|
||||
path, closer, err := client.ExtractChart("argo-cd", "0.7.1", "", false, math.MaxInt64, true)
|
||||
path, closer, err := client.ExtractChart("argo-cd", "0.7.1", false, math.MaxInt64, true)
|
||||
require.NoError(t, err)
|
||||
defer io.Close(closer)
|
||||
info, err := os.Stat(path)
|
||||
@@ -90,13 +90,13 @@ func Test_nativeHelmChart_ExtractChart(t *testing.T) {
|
||||
|
||||
func Test_nativeHelmChart_ExtractChartWithLimiter(t *testing.T) {
|
||||
client := NewClient("https://argoproj.github.io/argo-helm", HelmCreds{}, false, "", "")
|
||||
_, _, err := client.ExtractChart("argo-cd", "0.7.1", "", false, 100, false)
|
||||
_, _, err := client.ExtractChart("argo-cd", "0.7.1", false, 100, false)
|
||||
require.Error(t, err, "error while iterating on tar reader: unexpected EOF")
|
||||
}
|
||||
|
||||
func Test_nativeHelmChart_ExtractChart_insecure(t *testing.T) {
|
||||
client := NewClient("https://argoproj.github.io/argo-helm", HelmCreds{InsecureSkipVerify: true}, false, "", "")
|
||||
path, closer, err := client.ExtractChart("argo-cd", "0.7.1", "", false, math.MaxInt64, true)
|
||||
path, closer, err := client.ExtractChart("argo-cd", "0.7.1", false, math.MaxInt64, true)
|
||||
require.NoError(t, err)
|
||||
defer io.Close(closer)
|
||||
info, err := os.Stat(path)
|
||||
|
||||
32
util/helm/mocks/Client.go
generated
32
util/helm/mocks/Client.go
generated
@@ -14,17 +14,17 @@ type Client struct {
|
||||
mock.Mock
|
||||
}
|
||||
|
||||
// CleanChartCache provides a mock function with given fields: chart, version, project
|
||||
func (_m *Client) CleanChartCache(chart string, version string, project string) error {
|
||||
ret := _m.Called(chart, version, project)
|
||||
// CleanChartCache provides a mock function with given fields: chart, version
|
||||
func (_m *Client) CleanChartCache(chart string, version string) error {
|
||||
ret := _m.Called(chart, version)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for CleanChartCache")
|
||||
}
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(string, string, string) error); ok {
|
||||
r0 = rf(chart, version, project)
|
||||
if rf, ok := ret.Get(0).(func(string, string) error); ok {
|
||||
r0 = rf(chart, version)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
@@ -32,9 +32,9 @@ func (_m *Client) CleanChartCache(chart string, version string, project string)
|
||||
return r0
|
||||
}
|
||||
|
||||
// ExtractChart provides a mock function with given fields: chart, version, project, passCredentials, manifestMaxExtractedSize, disableManifestMaxExtractedSize
|
||||
func (_m *Client) ExtractChart(chart string, version string, project string, passCredentials bool, manifestMaxExtractedSize int64, disableManifestMaxExtractedSize bool) (string, io.Closer, error) {
|
||||
ret := _m.Called(chart, version, project, passCredentials, manifestMaxExtractedSize, disableManifestMaxExtractedSize)
|
||||
// ExtractChart provides a mock function with given fields: chart, version, passCredentials, manifestMaxExtractedSize, disableManifestMaxExtractedSize
|
||||
func (_m *Client) ExtractChart(chart string, version string, passCredentials bool, manifestMaxExtractedSize int64, disableManifestMaxExtractedSize bool) (string, io.Closer, error) {
|
||||
ret := _m.Called(chart, version, passCredentials, manifestMaxExtractedSize, disableManifestMaxExtractedSize)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for ExtractChart")
|
||||
@@ -43,25 +43,25 @@ func (_m *Client) ExtractChart(chart string, version string, project string, pas
|
||||
var r0 string
|
||||
var r1 io.Closer
|
||||
var r2 error
|
||||
if rf, ok := ret.Get(0).(func(string, string, string, bool, int64, bool) (string, io.Closer, error)); ok {
|
||||
return rf(chart, version, project, passCredentials, manifestMaxExtractedSize, disableManifestMaxExtractedSize)
|
||||
if rf, ok := ret.Get(0).(func(string, string, bool, int64, bool) (string, io.Closer, error)); ok {
|
||||
return rf(chart, version, passCredentials, manifestMaxExtractedSize, disableManifestMaxExtractedSize)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(string, string, string, bool, int64, bool) string); ok {
|
||||
r0 = rf(chart, version, project, passCredentials, manifestMaxExtractedSize, disableManifestMaxExtractedSize)
|
||||
if rf, ok := ret.Get(0).(func(string, string, bool, int64, bool) string); ok {
|
||||
r0 = rf(chart, version, passCredentials, manifestMaxExtractedSize, disableManifestMaxExtractedSize)
|
||||
} else {
|
||||
r0 = ret.Get(0).(string)
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(1).(func(string, string, string, bool, int64, bool) io.Closer); ok {
|
||||
r1 = rf(chart, version, project, passCredentials, manifestMaxExtractedSize, disableManifestMaxExtractedSize)
|
||||
if rf, ok := ret.Get(1).(func(string, string, bool, int64, bool) io.Closer); ok {
|
||||
r1 = rf(chart, version, passCredentials, manifestMaxExtractedSize, disableManifestMaxExtractedSize)
|
||||
} else {
|
||||
if ret.Get(1) != nil {
|
||||
r1 = ret.Get(1).(io.Closer)
|
||||
}
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(2).(func(string, string, string, bool, int64, bool) error); ok {
|
||||
r2 = rf(chart, version, project, passCredentials, manifestMaxExtractedSize, disableManifestMaxExtractedSize)
|
||||
if rf, ok := ret.Get(2).(func(string, string, bool, int64, bool) error); ok {
|
||||
r2 = rf(chart, version, passCredentials, manifestMaxExtractedSize, disableManifestMaxExtractedSize)
|
||||
} else {
|
||||
r2 = ret.Error(2)
|
||||
}
|
||||
|
||||
@@ -16,10 +16,29 @@ import (
|
||||
"k8s.io/client-go/tools/portforward"
|
||||
"k8s.io/client-go/transport/spdy"
|
||||
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
||||
"k8s.io/kubectl/pkg/util/podutils"
|
||||
|
||||
"github.com/argoproj/argo-cd/v3/util/io"
|
||||
)
|
||||
|
||||
func selectPodForPortForward(clientSet kubernetes.Interface, namespace string, podSelectors ...string) (*corev1.Pod, error) {
|
||||
for _, podSelector := range podSelectors {
|
||||
pods, err := clientSet.CoreV1().Pods(namespace).List(context.Background(), metav1.ListOptions{
|
||||
LabelSelector: podSelector,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, po := range pods.Items {
|
||||
if po.Status.Phase == corev1.PodRunning && podutils.IsPodReady(&po) {
|
||||
return &po, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil, fmt.Errorf("cannot find ready pod with selector: %v - use the --{component}-name flag in this command or set the environmental variable (Refer to https://argo-cd.readthedocs.io/en/stable/user-guide/environment-variables), to change the Argo CD component name in the CLI", podSelectors)
|
||||
}
|
||||
|
||||
func PortForward(targetPort int, namespace string, overrides *clientcmd.ConfigOverrides, podSelectors ...string) (int, error) {
|
||||
loadingRules := clientcmd.NewDefaultClientConfigLoadingRules()
|
||||
loadingRules.DefaultClientConfig = &clientcmd.DefaultClientConfig
|
||||
@@ -41,24 +60,9 @@ func PortForward(targetPort int, namespace string, overrides *clientcmd.ConfigOv
|
||||
return -1, err
|
||||
}
|
||||
|
||||
var pod *corev1.Pod
|
||||
|
||||
for _, podSelector := range podSelectors {
|
||||
pods, err := clientSet.CoreV1().Pods(namespace).List(context.Background(), metav1.ListOptions{
|
||||
LabelSelector: podSelector,
|
||||
})
|
||||
if err != nil {
|
||||
return -1, err
|
||||
}
|
||||
|
||||
if len(pods.Items) > 0 {
|
||||
pod = &pods.Items[0]
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if pod == nil {
|
||||
return -1, fmt.Errorf("cannot find pod with selector: %v - use the --{component}-name flag in this command or set the environmental variable (Refer to https://argo-cd.readthedocs.io/en/stable/user-guide/environment-variables), to change the Argo CD component name in the CLI", podSelectors)
|
||||
pod, err := selectPodForPortForward(clientSet, namespace, podSelectors...)
|
||||
if err != nil {
|
||||
return -1, err
|
||||
}
|
||||
|
||||
url := clientSet.CoreV1().RESTClient().Post().
|
||||
|
||||
83
util/kube/portforwarder_test.go
Normal file
83
util/kube/portforwarder_test.go
Normal file
@@ -0,0 +1,83 @@
|
||||
package kube
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/client-go/kubernetes/fake"
|
||||
)
|
||||
|
||||
func Test_selectPodForPortForward(t *testing.T) {
|
||||
// Mock the Kubernetes client
|
||||
client := fake.NewSimpleClientset(
|
||||
&corev1.Pod{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test-pod",
|
||||
Namespace: "default",
|
||||
Labels: map[string]string{
|
||||
"app": "test-app",
|
||||
},
|
||||
},
|
||||
Status: corev1.PodStatus{
|
||||
Conditions: []corev1.PodCondition{
|
||||
{
|
||||
Type: corev1.PodReady,
|
||||
Status: corev1.ConditionTrue,
|
||||
LastTransitionTime: metav1.Now(),
|
||||
},
|
||||
},
|
||||
Phase: corev1.PodRunning,
|
||||
},
|
||||
},
|
||||
&corev1.Pod{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test2-pod-broken",
|
||||
Namespace: "default",
|
||||
Labels: map[string]string{
|
||||
"app": "test2",
|
||||
},
|
||||
},
|
||||
Status: corev1.PodStatus{
|
||||
Conditions: []corev1.PodCondition{
|
||||
{
|
||||
Type: corev1.PodReady,
|
||||
Status: corev1.ConditionFalse,
|
||||
LastTransitionTime: metav1.Now(),
|
||||
},
|
||||
},
|
||||
Phase: corev1.PodFailed,
|
||||
},
|
||||
},
|
||||
&corev1.Pod{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test2-pod-working",
|
||||
Namespace: "default",
|
||||
Labels: map[string]string{
|
||||
"app": "test2",
|
||||
},
|
||||
},
|
||||
Status: corev1.PodStatus{
|
||||
Conditions: []corev1.PodCondition{
|
||||
{
|
||||
Type: corev1.PodReady,
|
||||
Status: corev1.ConditionTrue,
|
||||
LastTransitionTime: metav1.Now(),
|
||||
},
|
||||
},
|
||||
Phase: corev1.PodRunning,
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
// Test selecting the pod
|
||||
selectedPod, err := selectPodForPortForward(client, "default", "app=test-app")
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, "test-pod", selectedPod.Name)
|
||||
|
||||
// Test selecting the working pod
|
||||
selectedPod2, err := selectPodForPortForward(client, "default", "app=test2")
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, "test2-pod-working", selectedPod2.Name)
|
||||
}
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/Masterminds/semver/v3"
|
||||
"github.com/go-playground/webhooks/v6/azuredevops"
|
||||
"github.com/go-playground/webhooks/v6/bitbucket"
|
||||
bitbucketserver "github.com/go-playground/webhooks/v6/bitbucket-server"
|
||||
@@ -306,6 +307,22 @@ func (a *ArgoCDWebhookHandler) HandleEvent(payload any) {
|
||||
continue
|
||||
}
|
||||
for _, app := range filteredApps {
|
||||
if app.Spec.SourceHydrator != nil {
|
||||
drySource := app.Spec.SourceHydrator.GetDrySource()
|
||||
if sourceRevisionHasChanged(drySource, revision, touchedHead) && sourceUsesURL(drySource, webURL, repoRegexp) {
|
||||
refreshPaths := path.GetAppRefreshPaths(&app)
|
||||
if path.AppFilesHaveChanged(refreshPaths, changedFiles) {
|
||||
namespacedAppInterface := a.appClientset.ArgoprojV1alpha1().Applications(app.ObjectMeta.Namespace)
|
||||
log.Infof("webhook trigger refresh app to hydrate '%s'", app.ObjectMeta.Name)
|
||||
_, err = argo.RefreshApp(namespacedAppInterface, app.ObjectMeta.Name, v1alpha1.RefreshTypeNormal, true)
|
||||
if err != nil {
|
||||
log.Warnf("Failed to hydrate app '%s' for controller reprocessing: %v", app.ObjectMeta.Name, err)
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for _, source := range app.Spec.GetSources() {
|
||||
if sourceRevisionHasChanged(source, revision, touchedHead) && sourceUsesURL(source, webURL, repoRegexp) {
|
||||
refreshPaths := path.GetAppRefreshPaths(&app)
|
||||
@@ -413,11 +430,33 @@ func sourceRevisionHasChanged(source v1alpha1.ApplicationSource, revision string
|
||||
targetRevisionHasPrefixList := []string{"refs/heads/", "refs/tags/"}
|
||||
for _, prefix := range targetRevisionHasPrefixList {
|
||||
if strings.HasPrefix(source.TargetRevision, prefix) {
|
||||
return revision == targetRev
|
||||
return compareRevisions(revision, targetRev)
|
||||
}
|
||||
}
|
||||
|
||||
return source.TargetRevision == revision
|
||||
return compareRevisions(revision, source.TargetRevision)
|
||||
}
|
||||
|
||||
func compareRevisions(revision string, targetRevision string) bool {
|
||||
if revision == targetRevision {
|
||||
return true
|
||||
}
|
||||
|
||||
// If basic equality checking fails, it might be that the target revision is
|
||||
// a semver version constraint
|
||||
constraint, err := semver.NewConstraint(targetRevision)
|
||||
if err != nil {
|
||||
// The target revision is not a constraint
|
||||
return false
|
||||
}
|
||||
|
||||
version, err := semver.NewVersion(revision)
|
||||
if err != nil {
|
||||
// The new revision is not a valid semver version, so it can't match the constraint.
|
||||
return false
|
||||
}
|
||||
|
||||
return constraint.Check(version)
|
||||
}
|
||||
|
||||
func sourceUsesURL(source v1alpha1.ApplicationSource, webURL string, repoRegexp *regexp.Regexp) bool {
|
||||
|
||||
@@ -276,6 +276,72 @@ func TestGitHubCommitEvent_AppsInOtherNamespaces(t *testing.T) {
|
||||
hook.Reset()
|
||||
}
|
||||
|
||||
// TestGitHubCommitEvent_Hydrate makes sure that a webhook will hydrate an app when dry source changed.
|
||||
func TestGitHubCommitEvent_Hydrate(t *testing.T) {
|
||||
hook := test.NewGlobal()
|
||||
var patched bool
|
||||
reaction := func(action kubetesting.Action) (handled bool, ret runtime.Object, err error) {
|
||||
patchAction := action.(kubetesting.PatchAction)
|
||||
assert.Equal(t, "app-to-hydrate", patchAction.GetName())
|
||||
patched = true
|
||||
return true, nil, nil
|
||||
}
|
||||
h := NewMockHandler(&reactorDef{"patch", "applications", reaction}, []string{}, &v1alpha1.Application{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "app-to-hydrate",
|
||||
Namespace: "argocd",
|
||||
},
|
||||
Spec: v1alpha1.ApplicationSpec{
|
||||
SourceHydrator: &v1alpha1.SourceHydrator{
|
||||
DrySource: v1alpha1.DrySource{
|
||||
RepoURL: "https://github.com/jessesuen/test-repo",
|
||||
TargetRevision: "HEAD",
|
||||
Path: ".",
|
||||
},
|
||||
SyncSource: v1alpha1.SyncSource{
|
||||
TargetBranch: "environments/dev",
|
||||
Path: ".",
|
||||
},
|
||||
HydrateTo: nil,
|
||||
},
|
||||
},
|
||||
}, &v1alpha1.Application{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "app-to-ignore",
|
||||
},
|
||||
Spec: v1alpha1.ApplicationSpec{
|
||||
Sources: v1alpha1.ApplicationSources{
|
||||
{
|
||||
RepoURL: "https://github.com/some/unrelated-repo",
|
||||
Path: ".",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
)
|
||||
req := httptest.NewRequest(http.MethodPost, "/api/webhook", nil)
|
||||
req.Header.Set("X-GitHub-Event", "push")
|
||||
eventJSON, err := os.ReadFile("testdata/github-commit-event.json")
|
||||
require.NoError(t, err)
|
||||
req.Body = io.NopCloser(bytes.NewReader(eventJSON))
|
||||
w := httptest.NewRecorder()
|
||||
h.Handler(w, req)
|
||||
close(h.queue)
|
||||
h.Wait()
|
||||
assert.Equal(t, http.StatusOK, w.Code)
|
||||
assert.True(t, patched)
|
||||
|
||||
logMessages := make([]string, 0, len(hook.Entries))
|
||||
for _, entry := range hook.Entries {
|
||||
logMessages = append(logMessages, entry.Message)
|
||||
}
|
||||
|
||||
assert.Contains(t, logMessages, "webhook trigger refresh app to hydrate 'app-to-hydrate'")
|
||||
assert.NotContains(t, logMessages, "webhook trigger refresh app to hydrate 'app-to-ignore'")
|
||||
|
||||
hook.Reset()
|
||||
}
|
||||
|
||||
func TestGitHubTagEvent(t *testing.T) {
|
||||
hook := test.NewGlobal()
|
||||
h := NewMockHandler(nil, []string{})
|
||||
@@ -466,8 +532,15 @@ func TestAppRevisionHasChanged(t *testing.T) {
|
||||
{"dev target revision, dev, did not touch head", getSource("dev"), "dev", false, true},
|
||||
{"refs/heads/dev target revision, master, touched head", getSource("refs/heads/dev"), "master", true, false},
|
||||
{"refs/heads/dev target revision, dev, did not touch head", getSource("refs/heads/dev"), "dev", false, true},
|
||||
{"refs/tags/dev target revision, dev, did not touch head", getSource("refs/tags/dev"), "dev", false, true},
|
||||
{"env/test target revision, env/test, did not touch head", getSource("env/test"), "env/test", false, true},
|
||||
{"refs/heads/env/test target revision, env/test, did not touch head", getSource("refs/heads/env/test"), "env/test", false, true},
|
||||
{"refs/tags/env/test target revision, env/test, did not touch head", getSource("refs/tags/env/test"), "env/test", false, true},
|
||||
{"three/part/rev target revision, rev, did not touch head", getSource("three/part/rev"), "rev", false, false},
|
||||
{"1.* target revision (matching), 1.1.0, did not touch head", getSource("1.*"), "1.1.0", false, true},
|
||||
{"refs/tags/1.* target revision (matching), 1.1.0, did not touch head", getSource("refs/tags/1.*"), "1.1.0", false, true},
|
||||
{"1.* target revision (not matching), 2.0.0, did not touch head", getSource("1.*"), "2.0.0", false, false},
|
||||
{"1.* target revision, dev (not semver), did not touch head", getSource("1.*"), "dev", false, false},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
|
||||
Reference in New Issue
Block a user