mirror of
https://github.com/argoproj/argo-cd.git
synced 2026-02-28 21:48:46 +01:00
Compare commits
20 Commits
master
...
v3.1.0-rc3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
007a5aea6e | ||
|
|
36cc2d1b86 | ||
|
|
9db5e25e03 | ||
|
|
8eaccb7ea0 | ||
|
|
fed347da29 | ||
|
|
1cbd28cb30 | ||
|
|
6fe5ec794a | ||
|
|
6142c5bf56 | ||
|
|
563d45b8db | ||
|
|
37f2793e95 | ||
|
|
7224a15502 | ||
|
|
dd675feb33 | ||
|
|
c215dbf202 | ||
|
|
75f7016d89 | ||
|
|
4a7e581080 | ||
|
|
320f46f06b | ||
|
|
d69639a073 | ||
|
|
b75f532a91 | ||
|
|
200dc1d499 | ||
|
|
3f1d9bf5a2 |
@@ -21,7 +21,7 @@ builds:
|
||||
- -X github.com/argoproj/argo-cd/v3/common.gitCommit={{ .FullCommit }}
|
||||
- -X github.com/argoproj/argo-cd/v3/common.gitTreeState={{ .Env.GIT_TREE_STATE }}
|
||||
- -X github.com/argoproj/argo-cd/v3/common.kubectlVersion={{ .Env.KUBECTL_VERSION }}
|
||||
- '{{ if or (eq .Runtime.Goos "linux") (eq .Runtime.Goos "windows") }}-extldflags="-static"{{ end }}'
|
||||
- -extldflags="-static"
|
||||
goos:
|
||||
- linux
|
||||
- windows
|
||||
@@ -42,15 +42,6 @@ builds:
|
||||
goarch: ppc64le
|
||||
- goos: windows
|
||||
goarch: arm64
|
||||
overrides:
|
||||
- goos: darwin
|
||||
goarch: amd64
|
||||
env:
|
||||
- CGO_ENABLED=1
|
||||
- goos: darwin
|
||||
goarch: arm64
|
||||
env:
|
||||
- CGO_ENABLED=1
|
||||
|
||||
archives:
|
||||
- id: argocd-archive
|
||||
@@ -89,7 +80,7 @@ release:
|
||||
All Argo CD container images are signed by cosign. A Provenance is generated for container images and CLI binaries which meet the SLSA Level 3 specifications. See the [documentation](https://argo-cd.readthedocs.io/en/stable/operator-manual/signed-release-assets) on how to verify.
|
||||
|
||||
## Release Notes Blog Post
|
||||
For a detailed breakdown of the key changes and improvements in this release, check out the [official blog post](https://blog.argoproj.io/argo-cd-v3-0-release-candidate-a0b933f4e58f)
|
||||
For a detailed breakdown of the key changes and improvements in this release, check out the [official blog post](https://blog.argoproj.io/announcing-argo-cd-v3-1-f4389bc783c8)
|
||||
|
||||
## Upgrading
|
||||
|
||||
|
||||
81
assets/swagger.json
generated
81
assets/swagger.json
generated
@@ -1473,10 +1473,11 @@
|
||||
}
|
||||
},
|
||||
"post": {
|
||||
"description": "Deprecated: use RunResourceActionV2 instead. This version does not support resource action parameters but is\nmaintained for backward compatibility. It will be removed in a future release.",
|
||||
"tags": [
|
||||
"ApplicationService"
|
||||
],
|
||||
"summary": "RunResourceAction run resource action",
|
||||
"summary": "RunResourceAction runs a resource action",
|
||||
"operationId": "ApplicationService_RunResourceAction",
|
||||
"parameters": [
|
||||
{
|
||||
@@ -1490,7 +1491,81 @@
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/applicationResourceActionRunRequest"
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"name": "namespace",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"name": "resourceName",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"name": "version",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"name": "group",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"name": "kind",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"name": "appNamespace",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"name": "project",
|
||||
"in": "query"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "A successful response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/applicationApplicationResponse"
|
||||
}
|
||||
},
|
||||
"default": {
|
||||
"description": "An unexpected error response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/runtimeError"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/v1/applications/{name}/resource/actions/v2": {
|
||||
"post": {
|
||||
"tags": [
|
||||
"ApplicationService"
|
||||
],
|
||||
"summary": "RunResourceActionV2 runs a resource action with parameters",
|
||||
"operationId": "ApplicationService_RunResourceActionV2",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"name": "name",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "body",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/applicationResourceActionRunRequestV2"
|
||||
}
|
||||
}
|
||||
],
|
||||
@@ -5127,7 +5202,7 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"applicationResourceActionRunRequest": {
|
||||
"applicationResourceActionRunRequestV2": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"action": {
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
//go:build !darwin || (cgo && darwin)
|
||||
|
||||
package commands
|
||||
|
||||
import (
|
||||
25
cmd/argocd-k8s-auth/commands/azure_no_cgo.go
Normal file
25
cmd/argocd-k8s-auth/commands/azure_no_cgo.go
Normal file
@@ -0,0 +1,25 @@
|
||||
//go:build darwin && !cgo
|
||||
|
||||
// Package commands
|
||||
// This file is used when the GOOS is darwin and CGO is not enabled.
|
||||
// It provides a no-op implementation of newAzureCommand to allow goreleaser to build
|
||||
// a darwin binary on a linux machine.
|
||||
package commands
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"github.com/argoproj/argo-cd/v3/util/workloadidentity"
|
||||
)
|
||||
|
||||
func newAzureCommand() *cobra.Command {
|
||||
command := &cobra.Command{
|
||||
Use: "azure",
|
||||
Run: func(c *cobra.Command, _ []string) {
|
||||
log.Fatalf(workloadidentity.CGOError)
|
||||
},
|
||||
}
|
||||
return command
|
||||
}
|
||||
@@ -8,23 +8,23 @@ import (
|
||||
"strconv"
|
||||
"text/tabwriter"
|
||||
|
||||
"github.com/argoproj/argo-cd/v3/util/templates"
|
||||
|
||||
"github.com/argoproj/argo-cd/v3/cmd/util"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cobra"
|
||||
"google.golang.org/grpc/codes"
|
||||
"k8s.io/utils/ptr"
|
||||
"sigs.k8s.io/yaml"
|
||||
|
||||
"github.com/argoproj/argo-cd/v3/cmd/argocd/commands/headless"
|
||||
"github.com/argoproj/argo-cd/v3/cmd/util"
|
||||
argocdclient "github.com/argoproj/argo-cd/v3/pkg/apiclient"
|
||||
applicationpkg "github.com/argoproj/argo-cd/v3/pkg/apiclient/application"
|
||||
"github.com/argoproj/argo-cd/v3/pkg/apis/application"
|
||||
"github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1"
|
||||
"github.com/argoproj/argo-cd/v3/util/argo"
|
||||
"github.com/argoproj/argo-cd/v3/util/errors"
|
||||
"github.com/argoproj/argo-cd/v3/util/grpc"
|
||||
utilio "github.com/argoproj/argo-cd/v3/util/io"
|
||||
"github.com/argoproj/argo-cd/v3/util/templates"
|
||||
)
|
||||
|
||||
type DisplayedAction struct {
|
||||
@@ -192,7 +192,26 @@ func NewApplicationResourceActionsRunCommand(clientOpts *argocdclient.ClientOpti
|
||||
obj := filteredObjects[i]
|
||||
gvk := obj.GroupVersionKind()
|
||||
objResourceName := obj.GetName()
|
||||
_, err := appIf.RunResourceAction(ctx, &applicationpkg.ResourceActionRunRequest{
|
||||
_, err := appIf.RunResourceActionV2(ctx, &applicationpkg.ResourceActionRunRequestV2{
|
||||
Name: &appName,
|
||||
AppNamespace: &appNs,
|
||||
Namespace: ptr.To(obj.GetNamespace()),
|
||||
ResourceName: ptr.To(objResourceName),
|
||||
Group: ptr.To(gvk.Group),
|
||||
Kind: ptr.To(gvk.Kind),
|
||||
Version: ptr.To(gvk.GroupVersion().Version),
|
||||
Action: ptr.To(actionName),
|
||||
// TODO: add support for parameters
|
||||
})
|
||||
if err == nil {
|
||||
continue
|
||||
}
|
||||
if grpc.UnwrapGRPCStatus(err).Code() != codes.Unimplemented {
|
||||
errors.CheckError(err)
|
||||
}
|
||||
fmt.Println("RunResourceActionV2 is not supported by the server, falling back to RunResourceAction.")
|
||||
//nolint:staticcheck // RunResourceAction is deprecated, but we still need to support it for backward compatibility.
|
||||
_, err = appIf.RunResourceAction(ctx, &applicationpkg.ResourceActionRunRequest{
|
||||
Name: &appName,
|
||||
AppNamespace: &appNs,
|
||||
Namespace: ptr.To(obj.GetNamespace()),
|
||||
|
||||
@@ -2228,10 +2228,15 @@ func (c *fakeAppServiceClient) ListResourceActions(_ context.Context, _ *applica
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// nolint:staticcheck // ResourceActionRunRequest is deprecated, but we still need to implement it to satisfy the server interface.
|
||||
func (c *fakeAppServiceClient) RunResourceAction(_ context.Context, _ *applicationpkg.ResourceActionRunRequest, _ ...grpc.CallOption) (*applicationpkg.ApplicationResponse, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (c *fakeAppServiceClient) RunResourceActionV2(_ context.Context, _ *applicationpkg.ResourceActionRunRequestV2, _ ...grpc.CallOption) (*applicationpkg.ApplicationResponse, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (c *fakeAppServiceClient) DeleteResource(_ context.Context, _ *applicationpkg.ApplicationResourceDeleteRequest, _ ...grpc.CallOption) (*applicationpkg.ApplicationResponse, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
@@ -220,6 +220,7 @@ type hydratorMetadataFile struct {
|
||||
// Subject is the subject line of the DRY commit message, i.e. `git show --format=%s`.
|
||||
Subject string `json:"subject,omitempty"`
|
||||
// Body is the body of the DRY commit message, excluding the subject line, i.e. `git show --format=%b`.
|
||||
// Known Argocd- trailers with valid values are removed, but all other trailers are kept.
|
||||
Body string `json:"body,omitempty"`
|
||||
References []v1alpha1.RevisionReference `json:"references,omitempty"`
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ import (
|
||||
|
||||
"github.com/argoproj/argo-cd/v3/commitserver/apiclient"
|
||||
appv1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1"
|
||||
"github.com/argoproj/argo-cd/v3/util/git"
|
||||
"github.com/argoproj/argo-cd/v3/util/io"
|
||||
)
|
||||
|
||||
@@ -48,8 +49,10 @@ func WriteForPaths(root *os.Root, repoUrl, drySha string, dryCommitMetadata *app
|
||||
|
||||
subject, body, _ := strings.Cut(message, "\n\n")
|
||||
|
||||
_, bodyMinusTrailers := git.GetReferences(log.WithFields(log.Fields{"repo": repoUrl, "revision": drySha}), body)
|
||||
|
||||
// Write the top-level readme.
|
||||
err := writeMetadata(root, "", hydratorMetadataFile{DrySHA: drySha, RepoURL: repoUrl, Author: author, Subject: subject, Body: body, Date: date, References: references})
|
||||
err := writeMetadata(root, "", hydratorMetadataFile{DrySHA: drySha, RepoURL: repoUrl, Author: author, Subject: subject, Body: bodyMinusTrailers, Date: date, References: references})
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to write top-level hydrator metadata: %w", err)
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@ import (
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@@ -73,9 +72,13 @@ func TestWriteForPaths(t *testing.T) {
|
||||
|
||||
now := metav1.NewTime(time.Now())
|
||||
metadata := &appsv1.RevisionMetadata{
|
||||
Author: "test-author",
|
||||
Date: &now,
|
||||
Message: "test-message",
|
||||
Author: "test-author",
|
||||
Date: &now,
|
||||
Message: `test-message
|
||||
|
||||
Signed-off-by: Test User <test@example.com>
|
||||
Argocd-reference-commit-sha: abc123
|
||||
`,
|
||||
References: []appsv1.RevisionReference{
|
||||
{
|
||||
Commit: &appsv1.CommitMetadata{
|
||||
@@ -97,16 +100,15 @@ func TestWriteForPaths(t *testing.T) {
|
||||
topMetadataBytes, err := os.ReadFile(topMetadataPath)
|
||||
require.NoError(t, err)
|
||||
|
||||
expectedSubject, expectedBody, _ := strings.Cut(metadata.Message, "\n\n")
|
||||
|
||||
var topMetadata hydratorMetadataFile
|
||||
err = json.Unmarshal(topMetadataBytes, &topMetadata)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, repoURL, topMetadata.RepoURL)
|
||||
assert.Equal(t, drySha, topMetadata.DrySHA)
|
||||
assert.Equal(t, metadata.Author, topMetadata.Author)
|
||||
assert.Equal(t, expectedSubject, topMetadata.Subject)
|
||||
assert.Equal(t, expectedBody, topMetadata.Body)
|
||||
assert.Equal(t, "test-message", topMetadata.Subject)
|
||||
// The body should exclude the Argocd- trailers.
|
||||
assert.Equal(t, "Signed-off-by: Test User <test@example.com>\n", topMetadata.Body)
|
||||
assert.Equal(t, metadata.Date.Format(time.RFC3339), topMetadata.Date)
|
||||
assert.Equal(t, metadata.References, topMetadata.References)
|
||||
|
||||
|
||||
@@ -1483,7 +1483,7 @@ func (ctrl *ApplicationController) processRequestedAppOperation(app *appv1.Appli
|
||||
} else {
|
||||
state.Phase = synccommon.OperationRunning
|
||||
state.RetryCount++
|
||||
state.Message = fmt.Sprintf("%s. Retrying attempt #%d at %s.", state.Message, state.RetryCount, retryAt.Format(time.Kitchen))
|
||||
state.Message = fmt.Sprintf("%s due to application controller sync timeout. Retrying attempt #%d at %s.", state.Message, state.RetryCount, retryAt.Format(time.Kitchen))
|
||||
}
|
||||
} else if state.RetryCount > 0 {
|
||||
state.Message = fmt.Sprintf("%s (retried %d times).", state.Message, state.RetryCount)
|
||||
|
||||
@@ -2090,7 +2090,7 @@ func TestProcessRequestedAppOperation_FailedHasRetries(t *testing.T) {
|
||||
phase, _, _ := unstructured.NestedString(receivedPatch, "status", "operationState", "phase")
|
||||
assert.Equal(t, string(synccommon.OperationRunning), phase)
|
||||
message, _, _ := unstructured.NestedString(receivedPatch, "status", "operationState", "message")
|
||||
assert.Contains(t, message, "Retrying attempt #1")
|
||||
assert.Contains(t, message, "due to application controller sync timeout. Retrying attempt #1")
|
||||
retryCount, _, _ := unstructured.NestedFloat64(receivedPatch, "status", "operationState", "retryCount")
|
||||
assert.InEpsilon(t, float64(1), retryCount, 0.0001)
|
||||
}
|
||||
|
||||
@@ -108,15 +108,6 @@ func (m *appStateManager) SyncAppState(app *v1alpha1.Application, state *v1alpha
|
||||
}
|
||||
syncOp = *state.Operation.Sync
|
||||
|
||||
// validates if it should fail the sync if it finds shared resources
|
||||
hasSharedResource, sharedResourceMessage := hasSharedResourceCondition(app)
|
||||
if syncOp.SyncOptions.HasOption("FailOnSharedResource=true") &&
|
||||
hasSharedResource {
|
||||
state.Phase = common.OperationFailed
|
||||
state.Message = "Shared resource found: " + sharedResourceMessage
|
||||
return
|
||||
}
|
||||
|
||||
isMultiSourceRevision := app.Spec.HasMultipleSources()
|
||||
rollback := len(syncOp.Sources) > 0 || syncOp.Source != nil
|
||||
if rollback {
|
||||
@@ -207,6 +198,15 @@ func (m *appStateManager) SyncAppState(app *v1alpha1.Application, state *v1alpha
|
||||
syncRes.Revision = compareResult.syncStatus.Revision
|
||||
syncRes.Revisions = compareResult.syncStatus.Revisions
|
||||
|
||||
// validates if it should fail the sync if it finds shared resources
|
||||
hasSharedResource, sharedResourceMessage := hasSharedResourceCondition(app)
|
||||
if syncOp.SyncOptions.HasOption("FailOnSharedResource=true") &&
|
||||
hasSharedResource {
|
||||
state.Phase = common.OperationFailed
|
||||
state.Message = "Shared resource found: %s" + sharedResourceMessage
|
||||
return
|
||||
}
|
||||
|
||||
// If there are any comparison or spec errors error conditions do not perform the operation
|
||||
if errConditions := app.Status.GetConditions(map[v1alpha1.ApplicationConditionType]bool{
|
||||
v1alpha1.ApplicationConditionComparisonError: true,
|
||||
@@ -324,7 +324,7 @@ func (m *appStateManager) SyncAppState(app *v1alpha1.Application, state *v1alpha
|
||||
return
|
||||
}
|
||||
if impersonationEnabled {
|
||||
serviceAccountToImpersonate, err := deriveServiceAccountToImpersonate(proj, app)
|
||||
serviceAccountToImpersonate, err := deriveServiceAccountToImpersonate(proj, app, destCluster)
|
||||
if err != nil {
|
||||
state.Phase = common.OperationError
|
||||
state.Message = fmt.Sprintf("failed to find a matching service account to impersonate: %v", err)
|
||||
@@ -607,7 +607,7 @@ func syncWindowPreventsSync(app *v1alpha1.Application, proj *v1alpha1.AppProject
|
||||
|
||||
// deriveServiceAccountToImpersonate determines the service account to be used for impersonation for the sync operation.
|
||||
// The returned service account will be fully qualified including namespace and the service account name in the format system:serviceaccount:<namespace>:<service_account>
|
||||
func deriveServiceAccountToImpersonate(project *v1alpha1.AppProject, application *v1alpha1.Application) (string, error) {
|
||||
func deriveServiceAccountToImpersonate(project *v1alpha1.AppProject, application *v1alpha1.Application, destCluster *v1alpha1.Cluster) (string, error) {
|
||||
// spec.Destination.Namespace is optional. If not specified, use the Application's
|
||||
// namespace
|
||||
serviceAccountNamespace := application.Spec.Destination.Namespace
|
||||
@@ -617,7 +617,7 @@ func deriveServiceAccountToImpersonate(project *v1alpha1.AppProject, application
|
||||
// Loop through the destinationServiceAccounts and see if there is any destination that is a candidate.
|
||||
// if so, return the service account specified for that destination.
|
||||
for _, item := range project.Spec.DestinationServiceAccounts {
|
||||
dstServerMatched, err := glob.MatchWithError(item.Server, application.Spec.Destination.Server)
|
||||
dstServerMatched, err := glob.MatchWithError(item.Server, destCluster.Server)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("invalid glob pattern for destination server: %w", err)
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/argoproj/gitops-engine/pkg/sync"
|
||||
"github.com/argoproj/gitops-engine/pkg/sync/common"
|
||||
synccommon "github.com/argoproj/gitops-engine/pkg/sync/common"
|
||||
"github.com/argoproj/gitops-engine/pkg/utils/kube"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
@@ -14,6 +14,7 @@ import (
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
|
||||
"github.com/argoproj/argo-cd/v3/common"
|
||||
"github.com/argoproj/argo-cd/v3/controller/testdata"
|
||||
"github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1"
|
||||
"github.com/argoproj/argo-cd/v3/reposerver/apiclient"
|
||||
@@ -196,11 +197,15 @@ func TestAppStateManager_SyncAppState(t *testing.T) {
|
||||
controller *ApplicationController
|
||||
}
|
||||
|
||||
setup := func() *fixture {
|
||||
setup := func(liveObjects map[kube.ResourceKey]*unstructured.Unstructured) *fixture {
|
||||
app := newFakeApp()
|
||||
app.Status.OperationState = nil
|
||||
app.Status.History = nil
|
||||
|
||||
if liveObjects == nil {
|
||||
liveObjects = make(map[kube.ResourceKey]*unstructured.Unstructured)
|
||||
}
|
||||
|
||||
project := &v1alpha1.AppProject{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Namespace: test.FakeArgoCDNamespace,
|
||||
@@ -208,6 +213,12 @@ func TestAppStateManager_SyncAppState(t *testing.T) {
|
||||
},
|
||||
Spec: v1alpha1.AppProjectSpec{
|
||||
SignatureKeys: []v1alpha1.SignatureKey{{KeyID: "test"}},
|
||||
Destinations: []v1alpha1.ApplicationDestination{
|
||||
{
|
||||
Namespace: "*",
|
||||
Server: "*",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
data := fakeData{
|
||||
@@ -218,7 +229,7 @@ func TestAppStateManager_SyncAppState(t *testing.T) {
|
||||
Server: test.FakeClusterURL,
|
||||
Revision: "abc123",
|
||||
},
|
||||
managedLiveObjs: make(map[kube.ResourceKey]*unstructured.Unstructured),
|
||||
managedLiveObjs: liveObjects,
|
||||
}
|
||||
ctrl := newFakeController(&data, nil)
|
||||
|
||||
@@ -231,13 +242,23 @@ func TestAppStateManager_SyncAppState(t *testing.T) {
|
||||
t.Run("will fail the sync if finds shared resources", func(t *testing.T) {
|
||||
// given
|
||||
t.Parallel()
|
||||
f := setup()
|
||||
syncErrorMsg := "deployment already applied by another application"
|
||||
condition := v1alpha1.ApplicationCondition{
|
||||
Type: v1alpha1.ApplicationConditionSharedResourceWarning,
|
||||
Message: syncErrorMsg,
|
||||
}
|
||||
f.application.Status.Conditions = append(f.application.Status.Conditions, condition)
|
||||
|
||||
sharedObject := kube.MustToUnstructured(&corev1.ConfigMap{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
APIVersion: "v1",
|
||||
Kind: "ConfigMap",
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "configmap1",
|
||||
Namespace: "default",
|
||||
Annotations: map[string]string{
|
||||
common.AnnotationKeyAppInstance: "guestbook:/ConfigMap:default/configmap1",
|
||||
},
|
||||
},
|
||||
})
|
||||
liveObjects := make(map[kube.ResourceKey]*unstructured.Unstructured)
|
||||
liveObjects[kube.GetResourceKey(sharedObject)] = sharedObject
|
||||
f := setup(liveObjects)
|
||||
|
||||
// Sync with source unspecified
|
||||
opState := &v1alpha1.OperationState{Operation: v1alpha1.Operation{
|
||||
@@ -251,8 +272,8 @@ func TestAppStateManager_SyncAppState(t *testing.T) {
|
||||
f.controller.appStateManager.SyncAppState(f.application, opState)
|
||||
|
||||
// then
|
||||
assert.Equal(t, common.OperationFailed, opState.Phase)
|
||||
assert.Contains(t, opState.Message, syncErrorMsg)
|
||||
assert.Equal(t, synccommon.OperationFailed, opState.Phase)
|
||||
assert.Contains(t, opState.Message, "ConfigMap/configmap1 is part of applications fake-argocd-ns/my-app and guestbook")
|
||||
})
|
||||
}
|
||||
|
||||
@@ -315,13 +336,13 @@ func TestSyncWindowDeniesSync(t *testing.T) {
|
||||
Source: &v1alpha1.ApplicationSource{},
|
||||
},
|
||||
},
|
||||
Phase: common.OperationRunning,
|
||||
Phase: synccommon.OperationRunning,
|
||||
}
|
||||
// when
|
||||
f.controller.appStateManager.SyncAppState(f.application, opState)
|
||||
|
||||
// then
|
||||
assert.Equal(t, common.OperationRunning, opState.Phase)
|
||||
assert.Equal(t, synccommon.OperationRunning, opState.Phase)
|
||||
assert.Contains(t, opState.Message, opMessage)
|
||||
})
|
||||
}
|
||||
@@ -651,6 +672,7 @@ func TestDeriveServiceAccountMatchingNamespaces(t *testing.T) {
|
||||
type fixture struct {
|
||||
project *v1alpha1.AppProject
|
||||
application *v1alpha1.Application
|
||||
cluster *v1alpha1.Cluster
|
||||
}
|
||||
|
||||
setup := func(destinationServiceAccounts []v1alpha1.ApplicationDestinationServiceAccount, destinationNamespace, destinationServerURL, applicationNamespace string) *fixture {
|
||||
@@ -676,9 +698,14 @@ func TestDeriveServiceAccountMatchingNamespaces(t *testing.T) {
|
||||
},
|
||||
},
|
||||
}
|
||||
cluster := &v1alpha1.Cluster{
|
||||
Server: "https://kubernetes.svc.local",
|
||||
Name: "test-cluster",
|
||||
}
|
||||
return &fixture{
|
||||
project: project,
|
||||
application: app,
|
||||
cluster: cluster,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -694,7 +721,7 @@ func TestDeriveServiceAccountMatchingNamespaces(t *testing.T) {
|
||||
|
||||
f := setup(destinationServiceAccounts, destinationNamespace, destinationServerURL, applicationNamespace)
|
||||
// when
|
||||
sa, err := deriveServiceAccountToImpersonate(f.project, f.application)
|
||||
sa, err := deriveServiceAccountToImpersonate(f.project, f.application, f.cluster)
|
||||
assert.Equal(t, expectedSA, sa)
|
||||
|
||||
// then, there should be an error saying no valid match was found
|
||||
@@ -718,7 +745,7 @@ func TestDeriveServiceAccountMatchingNamespaces(t *testing.T) {
|
||||
|
||||
f := setup(destinationServiceAccounts, destinationNamespace, destinationServerURL, applicationNamespace)
|
||||
// when
|
||||
sa, err := deriveServiceAccountToImpersonate(f.project, f.application)
|
||||
sa, err := deriveServiceAccountToImpersonate(f.project, f.application, f.cluster)
|
||||
|
||||
// then, there should be no error and should use the right service account for impersonation
|
||||
require.NoError(t, err)
|
||||
@@ -757,7 +784,7 @@ func TestDeriveServiceAccountMatchingNamespaces(t *testing.T) {
|
||||
|
||||
f := setup(destinationServiceAccounts, destinationNamespace, destinationServerURL, applicationNamespace)
|
||||
// when
|
||||
sa, err := deriveServiceAccountToImpersonate(f.project, f.application)
|
||||
sa, err := deriveServiceAccountToImpersonate(f.project, f.application, f.cluster)
|
||||
|
||||
// then, there should be no error and should use the right service account for impersonation
|
||||
require.NoError(t, err)
|
||||
@@ -796,7 +823,7 @@ func TestDeriveServiceAccountMatchingNamespaces(t *testing.T) {
|
||||
|
||||
f := setup(destinationServiceAccounts, destinationNamespace, destinationServerURL, applicationNamespace)
|
||||
// when
|
||||
sa, err := deriveServiceAccountToImpersonate(f.project, f.application)
|
||||
sa, err := deriveServiceAccountToImpersonate(f.project, f.application, f.cluster)
|
||||
|
||||
// then, there should be no error and it should use the first matching service account for impersonation
|
||||
require.NoError(t, err)
|
||||
@@ -830,7 +857,7 @@ func TestDeriveServiceAccountMatchingNamespaces(t *testing.T) {
|
||||
|
||||
f := setup(destinationServiceAccounts, destinationNamespace, destinationServerURL, applicationNamespace)
|
||||
// when
|
||||
sa, err := deriveServiceAccountToImpersonate(f.project, f.application)
|
||||
sa, err := deriveServiceAccountToImpersonate(f.project, f.application, f.cluster)
|
||||
|
||||
// then, there should not be any error and should use the first matching glob pattern service account for impersonation
|
||||
require.NoError(t, err)
|
||||
@@ -865,7 +892,7 @@ func TestDeriveServiceAccountMatchingNamespaces(t *testing.T) {
|
||||
|
||||
f := setup(destinationServiceAccounts, destinationNamespace, destinationServerURL, applicationNamespace)
|
||||
// when
|
||||
sa, err := deriveServiceAccountToImpersonate(f.project, f.application)
|
||||
sa, err := deriveServiceAccountToImpersonate(f.project, f.application, f.cluster)
|
||||
|
||||
// then, there should be an error saying no match was found
|
||||
require.EqualError(t, err, expectedErrMsg)
|
||||
@@ -893,7 +920,7 @@ func TestDeriveServiceAccountMatchingNamespaces(t *testing.T) {
|
||||
|
||||
f := setup(destinationServiceAccounts, destinationNamespace, destinationServerURL, applicationNamespace)
|
||||
// when
|
||||
sa, err := deriveServiceAccountToImpersonate(f.project, f.application)
|
||||
sa, err := deriveServiceAccountToImpersonate(f.project, f.application, f.cluster)
|
||||
|
||||
// then, there should not be any error and the service account configured for with empty namespace should be used.
|
||||
require.NoError(t, err)
|
||||
@@ -927,7 +954,7 @@ func TestDeriveServiceAccountMatchingNamespaces(t *testing.T) {
|
||||
|
||||
f := setup(destinationServiceAccounts, destinationNamespace, destinationServerURL, applicationNamespace)
|
||||
// when
|
||||
sa, err := deriveServiceAccountToImpersonate(f.project, f.application)
|
||||
sa, err := deriveServiceAccountToImpersonate(f.project, f.application, f.cluster)
|
||||
|
||||
// then, there should not be any error and the catch all service account should be returned
|
||||
require.NoError(t, err)
|
||||
@@ -951,7 +978,7 @@ func TestDeriveServiceAccountMatchingNamespaces(t *testing.T) {
|
||||
|
||||
f := setup(destinationServiceAccounts, destinationNamespace, destinationServerURL, applicationNamespace)
|
||||
// when
|
||||
sa, err := deriveServiceAccountToImpersonate(f.project, f.application)
|
||||
sa, err := deriveServiceAccountToImpersonate(f.project, f.application, f.cluster)
|
||||
|
||||
// then, there must be an error as the glob pattern is invalid.
|
||||
require.ErrorContains(t, err, "invalid glob pattern for destination namespace")
|
||||
@@ -985,7 +1012,35 @@ func TestDeriveServiceAccountMatchingNamespaces(t *testing.T) {
|
||||
|
||||
f := setup(destinationServiceAccounts, destinationNamespace, destinationServerURL, applicationNamespace)
|
||||
// when
|
||||
sa, err := deriveServiceAccountToImpersonate(f.project, f.application)
|
||||
sa, err := deriveServiceAccountToImpersonate(f.project, f.application, f.cluster)
|
||||
assert.Equal(t, expectedSA, sa)
|
||||
|
||||
// then, there should not be any error and the service account with its namespace should be returned.
|
||||
require.NoError(t, err)
|
||||
})
|
||||
|
||||
t.Run("app destination name instead of server URL", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
destinationServiceAccounts := []v1alpha1.ApplicationDestinationServiceAccount{
|
||||
{
|
||||
Server: "https://kubernetes.svc.local",
|
||||
Namespace: "*",
|
||||
DefaultServiceAccount: "test-sa",
|
||||
},
|
||||
}
|
||||
destinationNamespace := "testns"
|
||||
destinationServerURL := "https://kubernetes.svc.local"
|
||||
applicationNamespace := "argocd-ns"
|
||||
expectedSA := "system:serviceaccount:testns:test-sa"
|
||||
|
||||
f := setup(destinationServiceAccounts, destinationNamespace, destinationServerURL, applicationNamespace)
|
||||
|
||||
// Use destination name instead of server URL
|
||||
f.application.Spec.Destination.Server = ""
|
||||
f.application.Spec.Destination.Name = f.cluster.Name
|
||||
|
||||
// when
|
||||
sa, err := deriveServiceAccountToImpersonate(f.project, f.application, f.cluster)
|
||||
assert.Equal(t, expectedSA, sa)
|
||||
|
||||
// then, there should not be any error and the service account with its namespace should be returned.
|
||||
@@ -999,6 +1054,7 @@ func TestDeriveServiceAccountMatchingServers(t *testing.T) {
|
||||
type fixture struct {
|
||||
project *v1alpha1.AppProject
|
||||
application *v1alpha1.Application
|
||||
cluster *v1alpha1.Cluster
|
||||
}
|
||||
|
||||
setup := func(destinationServiceAccounts []v1alpha1.ApplicationDestinationServiceAccount, destinationNamespace, destinationServerURL, applicationNamespace string) *fixture {
|
||||
@@ -1024,9 +1080,14 @@ func TestDeriveServiceAccountMatchingServers(t *testing.T) {
|
||||
},
|
||||
},
|
||||
}
|
||||
cluster := &v1alpha1.Cluster{
|
||||
Server: "https://kubernetes.svc.local",
|
||||
Name: "test-cluster",
|
||||
}
|
||||
return &fixture{
|
||||
project: project,
|
||||
application: app,
|
||||
cluster: cluster,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1062,7 +1123,7 @@ func TestDeriveServiceAccountMatchingServers(t *testing.T) {
|
||||
|
||||
f := setup(destinationServiceAccounts, destinationNamespace, destinationServerURL, applicationNamespace)
|
||||
// when
|
||||
sa, err := deriveServiceAccountToImpersonate(f.project, f.application)
|
||||
sa, err := deriveServiceAccountToImpersonate(f.project, f.application, f.cluster)
|
||||
|
||||
// then, there should not be any error and the right service account must be returned.
|
||||
require.NoError(t, err)
|
||||
@@ -1101,7 +1162,7 @@ func TestDeriveServiceAccountMatchingServers(t *testing.T) {
|
||||
|
||||
f := setup(destinationServiceAccounts, destinationNamespace, destinationServerURL, applicationNamespace)
|
||||
// when
|
||||
sa, err := deriveServiceAccountToImpersonate(f.project, f.application)
|
||||
sa, err := deriveServiceAccountToImpersonate(f.project, f.application, f.cluster)
|
||||
|
||||
// then, there should not be any error and first matching service account should be used
|
||||
require.NoError(t, err)
|
||||
@@ -1135,7 +1196,7 @@ func TestDeriveServiceAccountMatchingServers(t *testing.T) {
|
||||
|
||||
f := setup(destinationServiceAccounts, destinationNamespace, destinationServerURL, applicationNamespace)
|
||||
// when
|
||||
sa, err := deriveServiceAccountToImpersonate(f.project, f.application)
|
||||
sa, err := deriveServiceAccountToImpersonate(f.project, f.application, f.cluster)
|
||||
assert.Equal(t, expectedSA, sa)
|
||||
|
||||
// then, there should not be any error and the service account of the glob pattern, being the first match should be returned.
|
||||
@@ -1170,7 +1231,7 @@ func TestDeriveServiceAccountMatchingServers(t *testing.T) {
|
||||
|
||||
f := setup(destinationServiceAccounts, destinationNamespace, destinationServerURL, applicationNamespace)
|
||||
// when
|
||||
sa, err := deriveServiceAccountToImpersonate(f.project, f.application)
|
||||
sa, err := deriveServiceAccountToImpersonate(f.project, f.application, &v1alpha1.Cluster{Server: destinationServerURL})
|
||||
|
||||
// then, there an error with appropriate message must be returned
|
||||
require.EqualError(t, err, expectedErr)
|
||||
@@ -1204,7 +1265,7 @@ func TestDeriveServiceAccountMatchingServers(t *testing.T) {
|
||||
|
||||
f := setup(destinationServiceAccounts, destinationNamespace, destinationServerURL, applicationNamespace)
|
||||
// when
|
||||
sa, err := deriveServiceAccountToImpersonate(f.project, f.application)
|
||||
sa, err := deriveServiceAccountToImpersonate(f.project, f.application, f.cluster)
|
||||
|
||||
// then, there should not be any error and the service account of the glob pattern match must be returned.
|
||||
require.NoError(t, err)
|
||||
@@ -1228,7 +1289,7 @@ func TestDeriveServiceAccountMatchingServers(t *testing.T) {
|
||||
|
||||
f := setup(destinationServiceAccounts, destinationNamespace, destinationServerURL, applicationNamespace)
|
||||
// when
|
||||
sa, err := deriveServiceAccountToImpersonate(f.project, f.application)
|
||||
sa, err := deriveServiceAccountToImpersonate(f.project, f.application, f.cluster)
|
||||
|
||||
// then, there must be an error as the glob pattern is invalid.
|
||||
require.ErrorContains(t, err, "invalid glob pattern for destination server")
|
||||
@@ -1262,12 +1323,40 @@ func TestDeriveServiceAccountMatchingServers(t *testing.T) {
|
||||
|
||||
f := setup(destinationServiceAccounts, destinationNamespace, destinationServerURL, applicationNamespace)
|
||||
// when
|
||||
sa, err := deriveServiceAccountToImpersonate(f.project, f.application)
|
||||
sa, err := deriveServiceAccountToImpersonate(f.project, f.application, &v1alpha1.Cluster{Server: destinationServerURL})
|
||||
|
||||
// then, there should not be any error and the service account with the given namespace prefix must be returned.
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, expectedSA, sa)
|
||||
})
|
||||
|
||||
t.Run("app destination name instead of server URL", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
destinationServiceAccounts := []v1alpha1.ApplicationDestinationServiceAccount{
|
||||
{
|
||||
Server: "https://kubernetes.svc.local",
|
||||
Namespace: "*",
|
||||
DefaultServiceAccount: "test-sa",
|
||||
},
|
||||
}
|
||||
destinationNamespace := "testns"
|
||||
destinationServerURL := "https://kubernetes.svc.local"
|
||||
applicationNamespace := "argocd-ns"
|
||||
expectedSA := "system:serviceaccount:testns:test-sa"
|
||||
|
||||
f := setup(destinationServiceAccounts, destinationNamespace, destinationServerURL, applicationNamespace)
|
||||
|
||||
// Use destination name instead of server URL
|
||||
f.application.Spec.Destination.Server = ""
|
||||
f.application.Spec.Destination.Name = f.cluster.Name
|
||||
|
||||
// when
|
||||
sa, err := deriveServiceAccountToImpersonate(f.project, f.application, f.cluster)
|
||||
assert.Equal(t, expectedSA, sa)
|
||||
|
||||
// then, there should not be any error and the service account with its namespace should be returned.
|
||||
require.NoError(t, err)
|
||||
})
|
||||
}
|
||||
|
||||
func TestSyncWithImpersonate(t *testing.T) {
|
||||
@@ -1337,13 +1426,13 @@ func TestSyncWithImpersonate(t *testing.T) {
|
||||
Source: &v1alpha1.ApplicationSource{},
|
||||
},
|
||||
},
|
||||
Phase: common.OperationRunning,
|
||||
Phase: synccommon.OperationRunning,
|
||||
}
|
||||
// when
|
||||
f.controller.appStateManager.SyncAppState(f.application, opState)
|
||||
|
||||
// then, app sync should fail with expected error message in operation state
|
||||
assert.Equal(t, common.OperationError, opState.Phase)
|
||||
assert.Equal(t, synccommon.OperationError, opState.Phase)
|
||||
assert.Contains(t, opState.Message, opMessage)
|
||||
})
|
||||
|
||||
@@ -1358,13 +1447,13 @@ func TestSyncWithImpersonate(t *testing.T) {
|
||||
Source: &v1alpha1.ApplicationSource{},
|
||||
},
|
||||
},
|
||||
Phase: common.OperationRunning,
|
||||
Phase: synccommon.OperationRunning,
|
||||
}
|
||||
// when
|
||||
f.controller.appStateManager.SyncAppState(f.application, opState)
|
||||
|
||||
// then app sync should fail with expected error message in operation state
|
||||
assert.Equal(t, common.OperationError, opState.Phase)
|
||||
assert.Equal(t, synccommon.OperationError, opState.Phase)
|
||||
assert.Contains(t, opState.Message, opMessage)
|
||||
})
|
||||
|
||||
@@ -1379,13 +1468,13 @@ func TestSyncWithImpersonate(t *testing.T) {
|
||||
Source: &v1alpha1.ApplicationSource{},
|
||||
},
|
||||
},
|
||||
Phase: common.OperationRunning,
|
||||
Phase: synccommon.OperationRunning,
|
||||
}
|
||||
// when
|
||||
f.controller.appStateManager.SyncAppState(f.application, opState)
|
||||
|
||||
// then app sync should not fail
|
||||
assert.Equal(t, common.OperationSucceeded, opState.Phase)
|
||||
assert.Equal(t, synccommon.OperationSucceeded, opState.Phase)
|
||||
assert.Contains(t, opState.Message, opMessage)
|
||||
})
|
||||
|
||||
@@ -1400,13 +1489,38 @@ func TestSyncWithImpersonate(t *testing.T) {
|
||||
Source: &v1alpha1.ApplicationSource{},
|
||||
},
|
||||
},
|
||||
Phase: common.OperationRunning,
|
||||
Phase: synccommon.OperationRunning,
|
||||
}
|
||||
// when
|
||||
f.controller.appStateManager.SyncAppState(f.application, opState)
|
||||
|
||||
// then application sync should pass using the control plane service account
|
||||
assert.Equal(t, common.OperationSucceeded, opState.Phase)
|
||||
assert.Equal(t, synccommon.OperationSucceeded, opState.Phase)
|
||||
assert.Contains(t, opState.Message, opMessage)
|
||||
})
|
||||
|
||||
t.Run("app destination name instead of server URL", func(t *testing.T) {
|
||||
// given app sync impersonation feature is enabled with an application referring a project matching service account
|
||||
f := setup(true, test.FakeDestNamespace, "test-sa")
|
||||
opMessage := "successfully synced (no more tasks)"
|
||||
|
||||
opState := &v1alpha1.OperationState{
|
||||
Operation: v1alpha1.Operation{
|
||||
Sync: &v1alpha1.SyncOperation{
|
||||
Source: &v1alpha1.ApplicationSource{},
|
||||
},
|
||||
},
|
||||
Phase: synccommon.OperationRunning,
|
||||
}
|
||||
|
||||
f.application.Spec.Destination.Server = ""
|
||||
f.application.Spec.Destination.Name = "minikube"
|
||||
|
||||
// when
|
||||
f.controller.appStateManager.SyncAppState(f.application, opState)
|
||||
|
||||
// then app sync should not fail
|
||||
assert.Equal(t, synccommon.OperationSucceeded, opState.Phase)
|
||||
assert.Contains(t, opState.Message, opMessage)
|
||||
})
|
||||
}
|
||||
@@ -1474,7 +1588,7 @@ func TestClientSideApplyMigration(t *testing.T) {
|
||||
f.controller.appStateManager.SyncAppState(f.application, opState)
|
||||
|
||||
// then
|
||||
assert.Equal(t, common.OperationSucceeded, opState.Phase)
|
||||
assert.Equal(t, synccommon.OperationSucceeded, opState.Phase)
|
||||
assert.Contains(t, opState.Message, "successfully synced")
|
||||
})
|
||||
|
||||
@@ -1492,7 +1606,7 @@ func TestClientSideApplyMigration(t *testing.T) {
|
||||
f.controller.appStateManager.SyncAppState(f.application, opState)
|
||||
|
||||
// then
|
||||
assert.Equal(t, common.OperationSucceeded, opState.Phase)
|
||||
assert.Equal(t, synccommon.OperationSucceeded, opState.Phase)
|
||||
assert.Contains(t, opState.Message, "successfully synced")
|
||||
})
|
||||
|
||||
@@ -1510,7 +1624,7 @@ func TestClientSideApplyMigration(t *testing.T) {
|
||||
f.controller.appStateManager.SyncAppState(f.application, opState)
|
||||
|
||||
// then
|
||||
assert.Equal(t, common.OperationSucceeded, opState.Phase)
|
||||
assert.Equal(t, synccommon.OperationSucceeded, opState.Phase)
|
||||
assert.Contains(t, opState.Message, "successfully synced")
|
||||
})
|
||||
}
|
||||
|
||||
@@ -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.1 | v1.33, v1.32, v1.31, v1.30 |
|
||||
| 3.0 | v1.32, v1.31, v1.30, v1.29 |
|
||||
| 2.14 | v1.31, v1.30, v1.29, v1.28 |
|
||||
|
||||
@@ -7,6 +7,13 @@ applicable) restore Argo CD 2.x default behavior.
|
||||
Once 3.0 is released, no more 2.x minor versions will be released. We will continue to cut patch releases for the two
|
||||
most recent minor versions (so 2.14 until 3.2 is released and 2.13 until 3.1 is released).
|
||||
|
||||
## Images missing release notes on GitHub
|
||||
|
||||
!!! important
|
||||
Images 3.0.7 - 3.0.9 are missing release notes on GitHub. There was an issue with GoReleaser and building the darwin
|
||||
CLI that prevented the release notes from being published. More information can be found
|
||||
on [PR #23507](https://github.com/argoproj/argo-cd/pull/23507)
|
||||
|
||||
## Breaking Changes
|
||||
|
||||
### Fine-Grained RBAC for application `update` and `delete` sub-resources
|
||||
|
||||
@@ -20,6 +20,28 @@ The `--staticassets` directory in the API server (`/app/shared` by default) is n
|
||||
symlinks. This is to help protect against symlink attacks. If you have any symlinks in your `--staticassets` directory
|
||||
to a location outside the directory, they will return a 500 error starting with 3.1.
|
||||
|
||||
## v1 Actions API Deprecated
|
||||
|
||||
The `/api/v1/applications/{name}/resource/actions` endpoint is deprecated in favor of `/api/v1/applications/{name}/resource/actions/v2`.
|
||||
|
||||
This endpoint allows API users to run a custom resource action on a specific resource in an application.
|
||||
|
||||
The old endpoint accepted various parameters as query parameters. The POST body was the action name.
|
||||
|
||||
The new endpoint accepts all parameters as part of the POST body as a JSON object. The new endpoint also supports a new
|
||||
`resourceActionParameters` field to parameterize action runs.
|
||||
|
||||
The old endpoint will be removed in a future release, so users should migrate to the new endpoint as soon as possible.
|
||||
API clients will just need to change the endpoint URL and switch query string parameters to a JSON body.
|
||||
|
||||
If the old endpoint is used, the API will log a warning message:
|
||||
|
||||
> RunResourceAction was called. RunResourceAction is deprecated and will be removed in a future release. Use RunResourceActionV2 instead.
|
||||
|
||||
The CLI will fall back to the old endpoint if the new one is not available. If it falls back, it will log a warning message:
|
||||
|
||||
> RunResourceActionV2 is not supported by the server, falling back to RunResourceAction.
|
||||
|
||||
## OpenID Connect authorization code flow with PKCE is now handled by the server instead of the UI
|
||||
|
||||
Previously, when PKCE was enabled, the authorization code flow (the process which happens when you log in to Argo CD using OpenID Connect) was handled by the UI, whereas this flow was handled by the server if PKCE was not enabled. The server now always handles this flow, PKCE being enabled or not.
|
||||
@@ -37,3 +59,13 @@ If it returns `"enablePKCEAuthentication": true`, then PKCE is used.
|
||||
### Remediation
|
||||
|
||||
On your identity provider, ensure that the OIDC client used for Argo CD has the `/auth/callback` endpoint of your Argo CD URL (e.g. https://argocd.example.com/auth/callback) in the redirect URIs.
|
||||
|
||||
## Helm Upgraded to 3.18.4
|
||||
|
||||
Argo CD v3.1 upgrades the bundled Helm version to 3.18.4. There are no breaking changes in Helm 3.18 according to the
|
||||
[release notes](https://github.com/helm/helm/releases/tag/v3.18.0).
|
||||
|
||||
## Kustomize Upgraded to 5.7.0
|
||||
|
||||
Argo CD v3.1 upgrades the bundled Kustomize version to 5.7.0. There are no breaking changes in Kustomize 5.7 according
|
||||
to the [release notes](https://github.com/kubernetes-sigs/kustomize/releases/tag/kustomize%2Fv5.7.0).
|
||||
|
||||
@@ -230,6 +230,12 @@ The commit metadata will appear in the hydrated commit's root hydrator.metadata
|
||||
|
||||
```json
|
||||
{
|
||||
"author": "CI <ci@example.com>",
|
||||
"subject": "chore: bump image to b82add2",
|
||||
"date": "2025-06-09T13:50:08-04:00",
|
||||
"body": "Signed-off-by: CI <ci@example.com>\n",
|
||||
"drySha": "6cb951525937865dced818bbdd78c89b2d2b3045",
|
||||
"repoURL": "https://git.example.com/owner/manifests-repo",
|
||||
"references": [
|
||||
{
|
||||
"commit": {
|
||||
@@ -248,6 +254,10 @@ The commit metadata will appear in the hydrated commit's root hydrator.metadata
|
||||
}
|
||||
```
|
||||
|
||||
The top-level "body" field contains the commit message of the DRY commit minus the subject line and any
|
||||
`Argocd-reference-commit-*` trailers that were used in `references`. Unrecognized or invalid trailers are preserved in
|
||||
the body.
|
||||
|
||||
Although `references` is an array, the source hydrator currently only supports a single related commit. If a trailer is
|
||||
specified more than once, the last one will be used.
|
||||
|
||||
|
||||
@@ -1,12 +1,19 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
# Usage: ./add-helm-checksums.sh 3.9.4 # use the desired version
|
||||
# Usage: ./add-helm-checksums.sh <helm-version> # use the desired version e.g. 3.18.4
|
||||
|
||||
set -e
|
||||
|
||||
for arch in amd64 arm64 ppc64le s390x; do
|
||||
wget "https://get.helm.sh/helm-v$1-linux-$arch.tar.gz.sha256sum" -O "helm-v$1-linux-$arch.tar.gz.sha256"
|
||||
checksumfile="helm-v$1-linux-$arch.tar.gz.sha256"
|
||||
wget "https://get.helm.sh/helm-v$1-linux-$arch.tar.gz.sha256sum" -O "$checksumfile"
|
||||
outname="$(git rev-parse --show-toplevel)/hack/installers/checksums/helm-v$1-linux-$arch.tar.gz.sha256"
|
||||
mv $checksumfile $outname
|
||||
done
|
||||
|
||||
for arch in amd64 arm64; do
|
||||
wget "https://get.helm.sh/helm-v$1-darwin-$arch.tar.gz.sha256sum" -O "helm-v$1-darwin-$arch.tar.gz.sha256"
|
||||
checksumfile="helm-v$1-darwin-$arch.tar.gz.sha256"
|
||||
wget "https://get.helm.sh/helm-v$1-darwin-$arch.tar.gz.sha256sum" -O "$checksumfile"
|
||||
outname="$(git rev-parse --show-toplevel)/hack/installers/checksums/helm-v$1-darwin-$arch.tar.gz.sha256"
|
||||
mv $checksumfile $outname
|
||||
done
|
||||
@@ -0,0 +1 @@
|
||||
d186851d40b1999c5d75696bc0b754e4d29e860c8d0cf4c132ac1b1940c5cffc helm-v3.18.3-darwin-amd64.tar.gz
|
||||
@@ -0,0 +1 @@
|
||||
3fe3e9739ab3c75d88bfe13e464a79a2a7a804fc692c3258fa6a9d185d53e377 helm-v3.18.3-darwin-arm64.tar.gz
|
||||
@@ -0,0 +1 @@
|
||||
6ec85f306dd8fe9eb05c61ba4593182b2afcfefb52f21add3fe043ebbdc48e39 helm-v3.18.3-linux-amd64.tar.gz
|
||||
@@ -0,0 +1 @@
|
||||
3382ebdc6d6e027371551a63fc6e0a3073a1aec1061e346692932da61cfd8d24 helm-v3.18.3-linux-arm64.tar.gz
|
||||
@@ -0,0 +1 @@
|
||||
ca5ab0bb205488276095881f04b72bfed5c0ddb92f715940dde6a7ccae72818c helm-v3.18.3-linux-ppc64le.tar.gz
|
||||
@@ -0,0 +1 @@
|
||||
be261f040b59c04ad4f1ce6fc2f976e500167475cadb468bf78cb9772300fb5d helm-v3.18.3-linux-s390x.tar.gz
|
||||
@@ -0,0 +1 @@
|
||||
860a7238285b44b5dc7b3c4dad6194316885d7015d77c34e23177e0e9554af8f helm-v3.18.4-darwin-amd64.tar.gz
|
||||
@@ -0,0 +1 @@
|
||||
041849741550b20710d7ad0956e805ebd960b483fe978864f8e7fdd03ca84ec8 helm-v3.18.4-darwin-arm64.tar.gz
|
||||
@@ -0,0 +1 @@
|
||||
f8180838c23d7c7d797b208861fecb591d9ce1690d8704ed1e4cb8e2add966c1 helm-v3.18.4-linux-amd64.tar.gz
|
||||
@@ -0,0 +1 @@
|
||||
c0a45e67eef0c7416a8a8c9e9d5d2d30d70e4f4d3f7bea5de28241fffa8f3b89 helm-v3.18.4-linux-arm64.tar.gz
|
||||
@@ -0,0 +1 @@
|
||||
dbd74c59e7710f26e058596723abbf73662b553e01f40dfb08508ffffaeb7b81 helm-v3.18.4-linux-ppc64le.tar.gz
|
||||
@@ -0,0 +1 @@
|
||||
c8bafb34bcebd53494f0223239977e1ff7b487e714598a5843a0cb1788e20075 helm-v3.18.4-linux-s390x.tar.gz
|
||||
@@ -0,0 +1 @@
|
||||
277a7401f969ce3945e8f0ff8b0cce6f4353854db1ff89ba070001e3246e7f22 kustomize_5.7.0_darwin_amd64.tar.gz
|
||||
@@ -0,0 +1 @@
|
||||
c0dac68dc7870e1f673ae4d8fb554df971e0b9b9f0affc4be4c0852f62d0796e kustomize_5.7.0_darwin_arm64.tar.gz
|
||||
@@ -0,0 +1 @@
|
||||
0d98f06d6d2c2c0ff8923cc136a517af74aaa187f1b9f3e17ff370d0625ede84 kustomize_5.7.0_linux_amd64.tar.gz
|
||||
@@ -0,0 +1 @@
|
||||
744bb1bc1854b6634dea9eaf6db2f401a734ed25d6837baa6f91157d79c27d5e kustomize_5.7.0_linux_arm64.tar.gz
|
||||
@@ -0,0 +1 @@
|
||||
752e750d5f349156ea228ae01cf57be22e6cc29f0f05748a1bca7fa870393561 kustomize_5.7.0_linux_ppc64le.tar.gz
|
||||
@@ -0,0 +1 @@
|
||||
64898beb154a111c1a98f8cff066fdfa866c4c73505e9a9b5fa6ec39f0292558 kustomize_5.7.0_linux_s390x.tar.gz
|
||||
@@ -11,7 +11,7 @@
|
||||
# Use ./hack/installers/checksums/add-helm-checksums.sh and
|
||||
# add-kustomize-checksums.sh to help download checksums.
|
||||
###############################################################################
|
||||
helm3_version=3.17.1
|
||||
kustomize5_version=5.6.0
|
||||
helm3_version=3.18.4
|
||||
kustomize5_version=5.7.0
|
||||
protoc_version=29.3
|
||||
oras_version=1.2.0
|
||||
|
||||
@@ -3,25 +3,22 @@
|
||||
out="| Argo CD version | Kubernetes versions |\n"
|
||||
out+="|-----------------|---------------------|\n"
|
||||
|
||||
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]+\.//')
|
||||
argocd_current_version=$(git rev-parse --abbrev-ref HEAD | sed 's/release-//')
|
||||
argocd_major_version_num=$(echo "$argocd_current_version" | sed -E 's/\.[0-9]+//')
|
||||
argocd_minor_version_num=$(echo "$argocd_current_version" | sed -E 's/[0-9]+\.//')
|
||||
|
||||
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
|
||||
argocd_version="${argocd_major_version_num}.${argocd_minor_version_num}"
|
||||
git checkout "release-$argocd_version" > /dev/null || exit 1
|
||||
|
||||
line=$(yq '.jobs["test-e2e"].strategy.matrix |
|
||||
# k3s-version was an array prior to 2.12. This checks for the old format first and then falls back to the new format.
|
||||
(.["k3s-version"] // (.k3s | map(.version))) |
|
||||
.[]' .github/workflows/ci-build.yaml | \
|
||||
jq --arg minor_version "$minor_version" --raw-input --slurp --raw-output \
|
||||
'split("\n")[:-1] | map(sub("\\.[0-9]+$"; "")) | join(", ") | "| \($minor_version) | \(.) |"')
|
||||
jq --arg argocd_version "$argocd_version" --raw-input --slurp --raw-output \
|
||||
'split("\n")[:-1] | map(sub("\\.[0-9]+$"; "")) | join(", ") | "| \($argocd_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.
|
||||
@@ -29,13 +26,11 @@ for _ in {1..3}; do
|
||||
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
|
||||
else
|
||||
argocd_minor_version_num=$((argocd_minor_version_num - 1))
|
||||
fi
|
||||
done
|
||||
|
||||
git checkout "release-$argocd_minor_version"
|
||||
git checkout "release-$argocd_current_version"
|
||||
|
||||
printf "$out" > docs/operator-manual/tested-kubernetes-versions.md
|
||||
|
||||
@@ -253,6 +253,12 @@ spec:
|
||||
name: argocd-cmd-params-cm
|
||||
key: controller.cluster.cache.events.processing.interval
|
||||
optional: true
|
||||
- name: ARGOCD_APPLICATION_CONTROLLER_COMMIT_SERVER
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: argocd-cmd-params-cm
|
||||
key: commit.server
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
imagePullPolicy: Always
|
||||
name: argocd-application-controller
|
||||
|
||||
@@ -268,6 +268,12 @@ spec:
|
||||
name: argocd-cmd-params-cm
|
||||
key: controller.cluster.cache.events.processing.interval
|
||||
optional: true
|
||||
- name: ARGOCD_APPLICATION_CONTROLLER_COMMIT_SERVER
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: argocd-cmd-params-cm
|
||||
key: commit.server
|
||||
optional: true
|
||||
- name: KUBECACHEDIR
|
||||
value: /tmp/kubecache
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
|
||||
@@ -12,4 +12,4 @@ resources:
|
||||
images:
|
||||
- name: quay.io/argoproj/argocd
|
||||
newName: quay.io/argoproj/argocd
|
||||
newTag: latest
|
||||
newTag: v3.1.0-rc3
|
||||
|
||||
@@ -5,7 +5,7 @@ kind: Kustomization
|
||||
images:
|
||||
- name: quay.io/argoproj/argocd
|
||||
newName: quay.io/argoproj/argocd
|
||||
newTag: latest
|
||||
newTag: v3.1.0-rc3
|
||||
resources:
|
||||
- ./application-controller
|
||||
- ./dex
|
||||
|
||||
18
manifests/core-install-with-hydrator.yaml
generated
18
manifests/core-install-with-hydrator.yaml
generated
@@ -24699,7 +24699,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.1.0-rc3
|
||||
imagePullPolicy: Always
|
||||
name: argocd-applicationset-controller
|
||||
ports:
|
||||
@@ -24825,7 +24825,7 @@ spec:
|
||||
key: log.format.timestamp
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.1.0-rc3
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
failureThreshold: 3
|
||||
@@ -24953,7 +24953,7 @@ spec:
|
||||
- argocd
|
||||
- admin
|
||||
- redis-initial-password
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.1.0-rc3
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: secret-init
|
||||
securityContext:
|
||||
@@ -25226,7 +25226,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.1.0-rc3
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
failureThreshold: 3
|
||||
@@ -25278,7 +25278,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.1.0-rc3
|
||||
name: copyutil
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
@@ -25612,9 +25612,15 @@ spec:
|
||||
key: controller.cluster.cache.events.processing.interval
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: ARGOCD_APPLICATION_CONTROLLER_COMMIT_SERVER
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
key: commit.server
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: KUBECACHEDIR
|
||||
value: /tmp/kubecache
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.1.0-rc3
|
||||
imagePullPolicy: Always
|
||||
name: argocd-application-controller
|
||||
ports:
|
||||
|
||||
16
manifests/core-install.yaml
generated
16
manifests/core-install.yaml
generated
@@ -24667,7 +24667,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.1.0-rc3
|
||||
imagePullPolicy: Always
|
||||
name: argocd-applicationset-controller
|
||||
ports:
|
||||
@@ -24787,7 +24787,7 @@ spec:
|
||||
- argocd
|
||||
- admin
|
||||
- redis-initial-password
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.1.0-rc3
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: secret-init
|
||||
securityContext:
|
||||
@@ -25060,7 +25060,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.1.0-rc3
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
failureThreshold: 3
|
||||
@@ -25112,7 +25112,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.1.0-rc3
|
||||
name: copyutil
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
@@ -25446,9 +25446,15 @@ spec:
|
||||
key: controller.cluster.cache.events.processing.interval
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: ARGOCD_APPLICATION_CONTROLLER_COMMIT_SERVER
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
key: commit.server
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: KUBECACHEDIR
|
||||
value: /tmp/kubecache
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.1.0-rc3
|
||||
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.1.0-rc3
|
||||
|
||||
@@ -12,7 +12,7 @@ patches:
|
||||
images:
|
||||
- name: quay.io/argoproj/argocd
|
||||
newName: quay.io/argoproj/argocd
|
||||
newTag: latest
|
||||
newTag: v3.1.0-rc3
|
||||
resources:
|
||||
- ../../base/application-controller
|
||||
- ../../base/applicationset-controller
|
||||
|
||||
24
manifests/ha/install-with-hydrator.yaml
generated
24
manifests/ha/install-with-hydrator.yaml
generated
@@ -26065,7 +26065,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.1.0-rc3
|
||||
imagePullPolicy: Always
|
||||
name: argocd-applicationset-controller
|
||||
ports:
|
||||
@@ -26191,7 +26191,7 @@ spec:
|
||||
key: log.format.timestamp
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.1.0-rc3
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
failureThreshold: 3
|
||||
@@ -26342,7 +26342,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /shared/argocd-dex
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.1.0-rc3
|
||||
imagePullPolicy: Always
|
||||
name: copyutil
|
||||
securityContext:
|
||||
@@ -26438,7 +26438,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.1.0-rc3
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
tcpSocket:
|
||||
@@ -26562,7 +26562,7 @@ spec:
|
||||
- argocd
|
||||
- admin
|
||||
- redis-initial-password
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.1.0-rc3
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: secret-init
|
||||
securityContext:
|
||||
@@ -26861,7 +26861,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.1.0-rc3
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
failureThreshold: 3
|
||||
@@ -26913,7 +26913,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.1.0-rc3
|
||||
name: copyutil
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
@@ -27287,7 +27287,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.1.0-rc3
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
@@ -27657,9 +27657,15 @@ spec:
|
||||
key: controller.cluster.cache.events.processing.interval
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: ARGOCD_APPLICATION_CONTROLLER_COMMIT_SERVER
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
key: commit.server
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: KUBECACHEDIR
|
||||
value: /tmp/kubecache
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.1.0-rc3
|
||||
imagePullPolicy: Always
|
||||
name: argocd-application-controller
|
||||
ports:
|
||||
|
||||
22
manifests/ha/install.yaml
generated
22
manifests/ha/install.yaml
generated
@@ -26035,7 +26035,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.1.0-rc3
|
||||
imagePullPolicy: Always
|
||||
name: argocd-applicationset-controller
|
||||
ports:
|
||||
@@ -26178,7 +26178,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /shared/argocd-dex
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.1.0-rc3
|
||||
imagePullPolicy: Always
|
||||
name: copyutil
|
||||
securityContext:
|
||||
@@ -26274,7 +26274,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.1.0-rc3
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
tcpSocket:
|
||||
@@ -26398,7 +26398,7 @@ spec:
|
||||
- argocd
|
||||
- admin
|
||||
- redis-initial-password
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.1.0-rc3
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: secret-init
|
||||
securityContext:
|
||||
@@ -26697,7 +26697,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.1.0-rc3
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
failureThreshold: 3
|
||||
@@ -26749,7 +26749,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.1.0-rc3
|
||||
name: copyutil
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
@@ -27123,7 +27123,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.1.0-rc3
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
@@ -27493,9 +27493,15 @@ spec:
|
||||
key: controller.cluster.cache.events.processing.interval
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: ARGOCD_APPLICATION_CONTROLLER_COMMIT_SERVER
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
key: commit.server
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: KUBECACHEDIR
|
||||
value: /tmp/kubecache
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.1.0-rc3
|
||||
imagePullPolicy: Always
|
||||
name: argocd-application-controller
|
||||
ports:
|
||||
|
||||
24
manifests/ha/namespace-install-with-hydrator.yaml
generated
24
manifests/ha/namespace-install-with-hydrator.yaml
generated
@@ -1868,7 +1868,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.1.0-rc3
|
||||
imagePullPolicy: Always
|
||||
name: argocd-applicationset-controller
|
||||
ports:
|
||||
@@ -1994,7 +1994,7 @@ spec:
|
||||
key: log.format.timestamp
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.1.0-rc3
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
failureThreshold: 3
|
||||
@@ -2145,7 +2145,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /shared/argocd-dex
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.1.0-rc3
|
||||
imagePullPolicy: Always
|
||||
name: copyutil
|
||||
securityContext:
|
||||
@@ -2241,7 +2241,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.1.0-rc3
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
tcpSocket:
|
||||
@@ -2365,7 +2365,7 @@ spec:
|
||||
- argocd
|
||||
- admin
|
||||
- redis-initial-password
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.1.0-rc3
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: secret-init
|
||||
securityContext:
|
||||
@@ -2664,7 +2664,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.1.0-rc3
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
failureThreshold: 3
|
||||
@@ -2716,7 +2716,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.1.0-rc3
|
||||
name: copyutil
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
@@ -3090,7 +3090,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.1.0-rc3
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
@@ -3460,9 +3460,15 @@ spec:
|
||||
key: controller.cluster.cache.events.processing.interval
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: ARGOCD_APPLICATION_CONTROLLER_COMMIT_SERVER
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
key: commit.server
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: KUBECACHEDIR
|
||||
value: /tmp/kubecache
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.1.0-rc3
|
||||
imagePullPolicy: Always
|
||||
name: argocd-application-controller
|
||||
ports:
|
||||
|
||||
22
manifests/ha/namespace-install.yaml
generated
22
manifests/ha/namespace-install.yaml
generated
@@ -1838,7 +1838,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.1.0-rc3
|
||||
imagePullPolicy: Always
|
||||
name: argocd-applicationset-controller
|
||||
ports:
|
||||
@@ -1981,7 +1981,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /shared/argocd-dex
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.1.0-rc3
|
||||
imagePullPolicy: Always
|
||||
name: copyutil
|
||||
securityContext:
|
||||
@@ -2077,7 +2077,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.1.0-rc3
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
tcpSocket:
|
||||
@@ -2201,7 +2201,7 @@ spec:
|
||||
- argocd
|
||||
- admin
|
||||
- redis-initial-password
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.1.0-rc3
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: secret-init
|
||||
securityContext:
|
||||
@@ -2500,7 +2500,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.1.0-rc3
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
failureThreshold: 3
|
||||
@@ -2552,7 +2552,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.1.0-rc3
|
||||
name: copyutil
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
@@ -2926,7 +2926,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.1.0-rc3
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
@@ -3296,9 +3296,15 @@ spec:
|
||||
key: controller.cluster.cache.events.processing.interval
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: ARGOCD_APPLICATION_CONTROLLER_COMMIT_SERVER
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
key: commit.server
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: KUBECACHEDIR
|
||||
value: /tmp/kubecache
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.1.0-rc3
|
||||
imagePullPolicy: Always
|
||||
name: argocd-application-controller
|
||||
ports:
|
||||
|
||||
24
manifests/install-with-hydrator.yaml
generated
24
manifests/install-with-hydrator.yaml
generated
@@ -25159,7 +25159,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.1.0-rc3
|
||||
imagePullPolicy: Always
|
||||
name: argocd-applicationset-controller
|
||||
ports:
|
||||
@@ -25285,7 +25285,7 @@ spec:
|
||||
key: log.format.timestamp
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.1.0-rc3
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
failureThreshold: 3
|
||||
@@ -25436,7 +25436,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /shared/argocd-dex
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.1.0-rc3
|
||||
imagePullPolicy: Always
|
||||
name: copyutil
|
||||
securityContext:
|
||||
@@ -25532,7 +25532,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.1.0-rc3
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
tcpSocket:
|
||||
@@ -25634,7 +25634,7 @@ spec:
|
||||
- argocd
|
||||
- admin
|
||||
- redis-initial-password
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.1.0-rc3
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: secret-init
|
||||
securityContext:
|
||||
@@ -25907,7 +25907,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.1.0-rc3
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
failureThreshold: 3
|
||||
@@ -25959,7 +25959,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.1.0-rc3
|
||||
name: copyutil
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
@@ -26331,7 +26331,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.1.0-rc3
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
@@ -26701,9 +26701,15 @@ spec:
|
||||
key: controller.cluster.cache.events.processing.interval
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: ARGOCD_APPLICATION_CONTROLLER_COMMIT_SERVER
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
key: commit.server
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: KUBECACHEDIR
|
||||
value: /tmp/kubecache
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.1.0-rc3
|
||||
imagePullPolicy: Always
|
||||
name: argocd-application-controller
|
||||
ports:
|
||||
|
||||
22
manifests/install.yaml
generated
22
manifests/install.yaml
generated
@@ -25127,7 +25127,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.1.0-rc3
|
||||
imagePullPolicy: Always
|
||||
name: argocd-applicationset-controller
|
||||
ports:
|
||||
@@ -25270,7 +25270,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /shared/argocd-dex
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.1.0-rc3
|
||||
imagePullPolicy: Always
|
||||
name: copyutil
|
||||
securityContext:
|
||||
@@ -25366,7 +25366,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.1.0-rc3
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
tcpSocket:
|
||||
@@ -25468,7 +25468,7 @@ spec:
|
||||
- argocd
|
||||
- admin
|
||||
- redis-initial-password
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.1.0-rc3
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: secret-init
|
||||
securityContext:
|
||||
@@ -25741,7 +25741,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.1.0-rc3
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
failureThreshold: 3
|
||||
@@ -25793,7 +25793,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.1.0-rc3
|
||||
name: copyutil
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
@@ -26165,7 +26165,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.1.0-rc3
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
@@ -26535,9 +26535,15 @@ spec:
|
||||
key: controller.cluster.cache.events.processing.interval
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: ARGOCD_APPLICATION_CONTROLLER_COMMIT_SERVER
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
key: commit.server
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: KUBECACHEDIR
|
||||
value: /tmp/kubecache
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.1.0-rc3
|
||||
imagePullPolicy: Always
|
||||
name: argocd-application-controller
|
||||
ports:
|
||||
|
||||
24
manifests/namespace-install-with-hydrator.yaml
generated
24
manifests/namespace-install-with-hydrator.yaml
generated
@@ -962,7 +962,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.1.0-rc3
|
||||
imagePullPolicy: Always
|
||||
name: argocd-applicationset-controller
|
||||
ports:
|
||||
@@ -1088,7 +1088,7 @@ spec:
|
||||
key: log.format.timestamp
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.1.0-rc3
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
failureThreshold: 3
|
||||
@@ -1239,7 +1239,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /shared/argocd-dex
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.1.0-rc3
|
||||
imagePullPolicy: Always
|
||||
name: copyutil
|
||||
securityContext:
|
||||
@@ -1335,7 +1335,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.1.0-rc3
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
tcpSocket:
|
||||
@@ -1437,7 +1437,7 @@ spec:
|
||||
- argocd
|
||||
- admin
|
||||
- redis-initial-password
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.1.0-rc3
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: secret-init
|
||||
securityContext:
|
||||
@@ -1710,7 +1710,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.1.0-rc3
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
failureThreshold: 3
|
||||
@@ -1762,7 +1762,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.1.0-rc3
|
||||
name: copyutil
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
@@ -2134,7 +2134,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.1.0-rc3
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
@@ -2504,9 +2504,15 @@ spec:
|
||||
key: controller.cluster.cache.events.processing.interval
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: ARGOCD_APPLICATION_CONTROLLER_COMMIT_SERVER
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
key: commit.server
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: KUBECACHEDIR
|
||||
value: /tmp/kubecache
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.1.0-rc3
|
||||
imagePullPolicy: Always
|
||||
name: argocd-application-controller
|
||||
ports:
|
||||
|
||||
22
manifests/namespace-install.yaml
generated
22
manifests/namespace-install.yaml
generated
@@ -930,7 +930,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.1.0-rc3
|
||||
imagePullPolicy: Always
|
||||
name: argocd-applicationset-controller
|
||||
ports:
|
||||
@@ -1073,7 +1073,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /shared/argocd-dex
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.1.0-rc3
|
||||
imagePullPolicy: Always
|
||||
name: copyutil
|
||||
securityContext:
|
||||
@@ -1169,7 +1169,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.1.0-rc3
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
tcpSocket:
|
||||
@@ -1271,7 +1271,7 @@ spec:
|
||||
- argocd
|
||||
- admin
|
||||
- redis-initial-password
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.1.0-rc3
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: secret-init
|
||||
securityContext:
|
||||
@@ -1544,7 +1544,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.1.0-rc3
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
failureThreshold: 3
|
||||
@@ -1596,7 +1596,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.1.0-rc3
|
||||
name: copyutil
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
@@ -1968,7 +1968,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.1.0-rc3
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
@@ -2338,9 +2338,15 @@ spec:
|
||||
key: controller.cluster.cache.events.processing.interval
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: ARGOCD_APPLICATION_CONTROLLER_COMMIT_SERVER
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
key: commit.server
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: KUBECACHEDIR
|
||||
value: /tmp/kubecache
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.1.0-rc3
|
||||
imagePullPolicy: Always
|
||||
name: argocd-application-controller
|
||||
ports:
|
||||
|
||||
1099
pkg/apiclient/application/application.pb.go
generated
1099
pkg/apiclient/application/application.pb.go
generated
File diff suppressed because it is too large
Load Diff
@@ -1715,6 +1715,10 @@ func local_request_ApplicationService_ListResourceActions_0(ctx context.Context,
|
||||
|
||||
}
|
||||
|
||||
var (
|
||||
filter_ApplicationService_RunResourceAction_0 = &utilities.DoubleArray{Encoding: map[string]int{"action": 0, "name": 1}, Base: []int{1, 1, 2, 0, 0}, Check: []int{0, 1, 1, 2, 3}}
|
||||
)
|
||||
|
||||
func request_ApplicationService_RunResourceAction_0(ctx context.Context, marshaler runtime.Marshaler, client ApplicationServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq ResourceActionRunRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
@@ -1723,7 +1727,7 @@ func request_ApplicationService_RunResourceAction_0(ctx context.Context, marshal
|
||||
if berr != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
|
||||
}
|
||||
if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF {
|
||||
if err := marshaler.NewDecoder(newReader()).Decode(&protoReq.Action); err != nil && err != io.EOF {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
|
||||
@@ -1745,6 +1749,13 @@ func request_ApplicationService_RunResourceAction_0(ctx context.Context, marshal
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err)
|
||||
}
|
||||
|
||||
if err := req.ParseForm(); err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_ApplicationService_RunResourceAction_0); err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
|
||||
msg, err := client.RunResourceAction(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||
return msg, metadata, err
|
||||
|
||||
@@ -1754,6 +1765,48 @@ func local_request_ApplicationService_RunResourceAction_0(ctx context.Context, m
|
||||
var protoReq ResourceActionRunRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
newReader, berr := utilities.IOReaderFactory(req.Body)
|
||||
if berr != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
|
||||
}
|
||||
if err := marshaler.NewDecoder(newReader()).Decode(&protoReq.Action); err != nil && err != io.EOF {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
|
||||
var (
|
||||
val string
|
||||
ok bool
|
||||
err error
|
||||
_ = err
|
||||
)
|
||||
|
||||
val, ok = pathParams["name"]
|
||||
if !ok {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "name")
|
||||
}
|
||||
|
||||
protoReq.Name, err = runtime.StringP(val)
|
||||
|
||||
if err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err)
|
||||
}
|
||||
|
||||
if err := req.ParseForm(); err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_ApplicationService_RunResourceAction_0); err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
|
||||
msg, err := server.RunResourceAction(ctx, &protoReq)
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
func request_ApplicationService_RunResourceActionV2_0(ctx context.Context, marshaler runtime.Marshaler, client ApplicationServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq ResourceActionRunRequestV2
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
newReader, berr := utilities.IOReaderFactory(req.Body)
|
||||
if berr != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
|
||||
@@ -1780,7 +1833,42 @@ func local_request_ApplicationService_RunResourceAction_0(ctx context.Context, m
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err)
|
||||
}
|
||||
|
||||
msg, err := server.RunResourceAction(ctx, &protoReq)
|
||||
msg, err := client.RunResourceActionV2(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
func local_request_ApplicationService_RunResourceActionV2_0(ctx context.Context, marshaler runtime.Marshaler, server ApplicationServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq ResourceActionRunRequestV2
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
newReader, berr := utilities.IOReaderFactory(req.Body)
|
||||
if berr != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
|
||||
}
|
||||
if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
|
||||
var (
|
||||
val string
|
||||
ok bool
|
||||
err error
|
||||
_ = err
|
||||
)
|
||||
|
||||
val, ok = pathParams["name"]
|
||||
if !ok {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "name")
|
||||
}
|
||||
|
||||
protoReq.Name, err = runtime.StringP(val)
|
||||
|
||||
if err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err)
|
||||
}
|
||||
|
||||
msg, err := server.RunResourceActionV2(ctx, &protoReq)
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
@@ -2637,6 +2725,29 @@ func RegisterApplicationServiceHandlerServer(ctx context.Context, mux *runtime.S
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("POST", pattern_ApplicationService_RunResourceActionV2_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
var stream runtime.ServerTransportStream
|
||||
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := local_request_ApplicationService_RunResourceActionV2_0(rctx, inboundMarshaler, server, req, pathParams)
|
||||
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
|
||||
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_ApplicationService_RunResourceActionV2_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("DELETE", pattern_ApplicationService_DeleteResource_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
@@ -3261,6 +3372,26 @@ func RegisterApplicationServiceHandlerClient(ctx context.Context, mux *runtime.S
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("POST", pattern_ApplicationService_RunResourceActionV2_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
rctx, err := runtime.AnnotateContext(ctx, mux, req)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := request_ApplicationService_RunResourceActionV2_0(rctx, inboundMarshaler, client, req, pathParams)
|
||||
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_ApplicationService_RunResourceActionV2_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("DELETE", pattern_ApplicationService_DeleteResource_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
@@ -3415,6 +3546,8 @@ var (
|
||||
|
||||
pattern_ApplicationService_RunResourceAction_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3, 2, 4, 2, 5}, []string{"api", "v1", "applications", "name", "resource", "actions"}, "", runtime.AssumeColonVerbOpt(true)))
|
||||
|
||||
pattern_ApplicationService_RunResourceActionV2_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3, 2, 4, 2, 5, 2, 6}, []string{"api", "v1", "applications", "name", "resource", "actions", "v2"}, "", runtime.AssumeColonVerbOpt(true)))
|
||||
|
||||
pattern_ApplicationService_DeleteResource_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3, 2, 4}, []string{"api", "v1", "applications", "name", "resource"}, "", runtime.AssumeColonVerbOpt(true)))
|
||||
|
||||
pattern_ApplicationService_PodLogs_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3, 2, 4, 1, 0, 4, 1, 5, 5, 2, 6}, []string{"api", "v1", "applications", "name", "pods", "podName", "logs"}, "", runtime.AssumeColonVerbOpt(true)))
|
||||
@@ -3477,6 +3610,8 @@ var (
|
||||
|
||||
forward_ApplicationService_RunResourceAction_0 = runtime.ForwardResponseMessage
|
||||
|
||||
forward_ApplicationService_RunResourceActionV2_0 = runtime.ForwardResponseMessage
|
||||
|
||||
forward_ApplicationService_DeleteResource_0 = runtime.ForwardResponseMessage
|
||||
|
||||
forward_ApplicationService_PodLogs_0 = runtime.ForwardResponseStream
|
||||
|
||||
@@ -20,23 +20,29 @@ if #obj.status.conditions == 0 then
|
||||
end
|
||||
|
||||
local isEstablished
|
||||
local isTerminating
|
||||
local namesNotAccepted
|
||||
local hasViolations
|
||||
local conditionMsg = ""
|
||||
|
||||
for _, condition in pairs(obj.status.conditions) do
|
||||
|
||||
-- Check if CRD is terminating
|
||||
if condition.type == "Terminating" and condition.status == "True" then
|
||||
isTerminating = true
|
||||
conditionMsg = condition.message
|
||||
hs.status = "Progressing"
|
||||
hs.message = "CRD is terminating: " .. condition.message
|
||||
return hs
|
||||
end
|
||||
|
||||
-- Check if K8s has accepted names for this CRD
|
||||
if condition.type == "NamesAccepted" and condition.status == "False" then
|
||||
namesNotAccepted = true
|
||||
conditionMsg = condition.message
|
||||
hs.status = "Degraded"
|
||||
hs.message = "CRD names have not been accepted: " .. condition.message
|
||||
return hs
|
||||
end
|
||||
|
||||
-- Checking if CRD has violations
|
||||
if condition.type == "NonStructuralSchema" and condition.status == "True" then
|
||||
hs.status = "Degraded"
|
||||
hs.message = "Schema violations found: " .. condition.message
|
||||
return hs
|
||||
end
|
||||
|
||||
-- Checking if CRD is established
|
||||
@@ -44,25 +50,6 @@ for _, condition in pairs(obj.status.conditions) do
|
||||
isEstablished = true
|
||||
conditionMsg = condition.message
|
||||
end
|
||||
|
||||
-- Checking if CRD has violations
|
||||
if condition.type == "NonStructuralSchema" and condition.status == "True" then
|
||||
hasViolations = true
|
||||
conditionMsg = condition.message
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
if isTerminating then
|
||||
hs.status = "Progressing"
|
||||
hs.message = "CRD is terminating: " .. conditionMsg
|
||||
return hs
|
||||
end
|
||||
|
||||
if namesNotAccepted then
|
||||
hs.status = "Degraded"
|
||||
hs.message = "CRD names have not been accepted: " .. conditionMsg
|
||||
return hs
|
||||
end
|
||||
|
||||
if not isEstablished then
|
||||
@@ -71,12 +58,6 @@ if not isEstablished then
|
||||
return hs
|
||||
end
|
||||
|
||||
if hasViolations then
|
||||
hs.status = "Degraded"
|
||||
hs.message = "Schema violations found: " .. conditionMsg
|
||||
return hs
|
||||
end
|
||||
|
||||
hs.status = "Healthy"
|
||||
hs.message = "CRD is healthy"
|
||||
return hs
|
||||
@@ -47,15 +47,15 @@ status:
|
||||
reason: NoConflicts
|
||||
status: 'True'
|
||||
type: NamesAccepted
|
||||
- lastTransitionTime: '2024-05-19T23:35:28Z'
|
||||
message: the initial names have been accepted
|
||||
reason: InitialNamesAccepted
|
||||
status: 'True'
|
||||
type: Established
|
||||
- lastTransitionTime: '2024-10-26T19:44:57Z'
|
||||
message: 'spec.preserveUnknownFields: Invalid value: true: must be false'
|
||||
reason: Violations
|
||||
status: 'True'
|
||||
type: NonStructuralSchema
|
||||
- lastTransitionTime: '2024-05-19T23:35:28Z'
|
||||
message: the initial names have been accepted
|
||||
reason: InitialNamesAccepted
|
||||
status: 'True'
|
||||
type: Established
|
||||
storedVersions:
|
||||
- v1alpha1
|
||||
@@ -2497,7 +2497,32 @@ func (s *Server) getAvailableActions(resourceOverrides map[string]v1alpha1.Resou
|
||||
return availableActions, nil
|
||||
}
|
||||
|
||||
// RunResourceAction runs a resource action on a live resource
|
||||
//
|
||||
// Deprecated: use RunResourceActionV2 instead. This version does not support resource action parameters but is
|
||||
// maintained for backward compatibility. It will be removed in a future release.
|
||||
func (s *Server) RunResourceAction(ctx context.Context, q *application.ResourceActionRunRequest) (*application.ApplicationResponse, error) {
|
||||
log.WithFields(log.Fields{
|
||||
"action": q.Action,
|
||||
"application": q.Name,
|
||||
"app-namespace": q.AppNamespace,
|
||||
"project": q.Project,
|
||||
"user": session.Username(ctx),
|
||||
}).Warn("RunResourceAction was called. RunResourceAction is deprecated and will be removed in a future release. Use RunResourceActionV2 instead.")
|
||||
qV2 := &application.ResourceActionRunRequestV2{
|
||||
Name: q.Name,
|
||||
AppNamespace: q.AppNamespace,
|
||||
Namespace: q.Namespace,
|
||||
ResourceName: q.ResourceName,
|
||||
Kind: q.Kind,
|
||||
Version: q.Version,
|
||||
Group: q.Group,
|
||||
Project: q.Project,
|
||||
}
|
||||
return s.RunResourceActionV2(ctx, qV2)
|
||||
}
|
||||
|
||||
func (s *Server) RunResourceActionV2(ctx context.Context, q *application.ResourceActionRunRequestV2) (*application.ApplicationResponse, error) {
|
||||
resourceRequest := &application.ApplicationResourceRequest{
|
||||
Name: q.Name,
|
||||
AppNamespace: q.AppNamespace,
|
||||
|
||||
@@ -208,7 +208,22 @@ message ResourceActionParameters {
|
||||
required string value = 2;
|
||||
}
|
||||
|
||||
// ResourceActionRunRequest is a request to run a resource action.
|
||||
// This message is deprecated and replaced by ResourceActionRunRequestV2.
|
||||
message ResourceActionRunRequest {
|
||||
option deprecated = true;
|
||||
required string name = 1;
|
||||
optional string namespace = 2;
|
||||
required string resourceName = 3;
|
||||
required string version = 4;
|
||||
optional string group = 5;
|
||||
required string kind = 6;
|
||||
required string action = 7;
|
||||
optional string appNamespace = 8;
|
||||
optional string project = 9;
|
||||
}
|
||||
|
||||
message ResourceActionRunRequestV2 {
|
||||
required string name = 1;
|
||||
optional string namespace = 2;
|
||||
required string resourceName = 3;
|
||||
@@ -470,10 +485,22 @@ service ApplicationService {
|
||||
option (google.api.http).get = "/api/v1/applications/{name}/resource/actions";
|
||||
}
|
||||
|
||||
// RunResourceAction run resource action
|
||||
// RunResourceAction runs a resource action
|
||||
//
|
||||
// Deprecated: use RunResourceActionV2 instead. This version does not support resource action parameters but is
|
||||
// maintained for backward compatibility. It will be removed in a future release.
|
||||
rpc RunResourceAction(ResourceActionRunRequest) returns (ApplicationResponse) {
|
||||
option deprecated = true;
|
||||
option (google.api.http) = {
|
||||
post: "/api/v1/applications/{name}/resource/actions"
|
||||
body: "action"
|
||||
};
|
||||
}
|
||||
|
||||
// RunResourceActionV2 runs a resource action with parameters
|
||||
rpc RunResourceActionV2(ResourceActionRunRequestV2) returns (ApplicationResponse) {
|
||||
option (google.api.http) = {
|
||||
post: "/api/v1/applications/{name}/resource/actions/v2"
|
||||
body: "*"
|
||||
};
|
||||
}
|
||||
|
||||
@@ -989,15 +989,15 @@ func TestNoAppEnumeration(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("RunResourceAction", func(t *testing.T) {
|
||||
_, err := appServer.RunResourceAction(adminCtx, &application.ResourceActionRunRequest{Name: ptr.To("test"), ResourceName: ptr.To("test"), Group: ptr.To("apps"), Kind: ptr.To("Deployment"), Namespace: ptr.To("test"), Action: ptr.To("restart")})
|
||||
_, err := appServer.RunResourceActionV2(adminCtx, &application.ResourceActionRunRequestV2{Name: ptr.To("test"), ResourceName: ptr.To("test"), Group: ptr.To("apps"), Kind: ptr.To("Deployment"), Namespace: ptr.To("test"), Action: ptr.To("restart")})
|
||||
require.NoError(t, err)
|
||||
_, err = appServer.RunResourceAction(noRoleCtx, &application.ResourceActionRunRequest{Name: ptr.To("test")})
|
||||
_, err = appServer.RunResourceActionV2(noRoleCtx, &application.ResourceActionRunRequestV2{Name: ptr.To("test")})
|
||||
require.EqualError(t, err, common.PermissionDeniedAPIError.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence")
|
||||
_, err = appServer.RunResourceAction(noRoleCtx, &application.ResourceActionRunRequest{Group: ptr.To("argoproj.io"), Kind: ptr.To("Application"), Name: ptr.To("test")})
|
||||
_, err = appServer.RunResourceActionV2(noRoleCtx, &application.ResourceActionRunRequestV2{Group: ptr.To("argoproj.io"), Kind: ptr.To("Application"), Name: ptr.To("test")})
|
||||
require.EqualError(t, err, common.PermissionDeniedAPIError.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence")
|
||||
_, err = appServer.RunResourceAction(adminCtx, &application.ResourceActionRunRequest{Name: ptr.To("doest-not-exist")})
|
||||
_, err = appServer.RunResourceActionV2(adminCtx, &application.ResourceActionRunRequestV2{Name: ptr.To("doest-not-exist")})
|
||||
require.EqualError(t, err, common.PermissionDeniedAPIError.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence")
|
||||
_, err = appServer.RunResourceAction(adminCtx, &application.ResourceActionRunRequest{Name: ptr.To("doest-not-exist"), Project: ptr.To("test")})
|
||||
_, err = appServer.RunResourceActionV2(adminCtx, &application.ResourceActionRunRequestV2{Name: ptr.To("doest-not-exist"), Project: ptr.To("test")})
|
||||
assert.EqualError(t, err, "rpc error: code = NotFound desc = applications.argoproj.io \"doest-not-exist\" not found", "when the request specifies a project, we can return the standard k8s error message")
|
||||
})
|
||||
|
||||
@@ -2536,7 +2536,7 @@ func TestRunNewStyleResourceAction(t *testing.T) {
|
||||
err := appStateCache.SetAppResourcesTree(testApp.Name, &v1alpha1.ApplicationTree{Nodes: nodes})
|
||||
require.NoError(t, err)
|
||||
|
||||
appResponse, runErr := appServer.RunResourceAction(t.Context(), &application.ResourceActionRunRequest{
|
||||
appResponse, runErr := appServer.RunResourceActionV2(t.Context(), &application.ResourceActionRunRequestV2{
|
||||
Name: &testApp.Name,
|
||||
Namespace: &namespace,
|
||||
Action: &action,
|
||||
@@ -2562,7 +2562,7 @@ func TestRunNewStyleResourceAction(t *testing.T) {
|
||||
err := appStateCache.SetAppResourcesTree(testApp.Name, &v1alpha1.ApplicationTree{Nodes: nodes})
|
||||
require.NoError(t, err)
|
||||
|
||||
appResponse, runErr := appServer.RunResourceAction(t.Context(), &application.ResourceActionRunRequest{
|
||||
appResponse, runErr := appServer.RunResourceActionV2(t.Context(), &application.ResourceActionRunRequestV2{
|
||||
Name: &testApp.Name,
|
||||
Namespace: &namespace,
|
||||
Action: &action,
|
||||
@@ -2633,7 +2633,7 @@ func TestRunOldStyleResourceAction(t *testing.T) {
|
||||
err := appStateCache.SetAppResourcesTree(testApp.Name, &v1alpha1.ApplicationTree{Nodes: nodes})
|
||||
require.NoError(t, err)
|
||||
|
||||
appResponse, runErr := appServer.RunResourceAction(t.Context(), &application.ResourceActionRunRequest{
|
||||
appResponse, runErr := appServer.RunResourceActionV2(t.Context(), &application.ResourceActionRunRequestV2{
|
||||
Name: &testApp.Name,
|
||||
Namespace: &namespace,
|
||||
Action: &action,
|
||||
|
||||
@@ -875,7 +875,7 @@ func TestNamespacedResourceAction(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, []*ResourceAction{{Name: "sample", Disabled: false}}, actions.Actions)
|
||||
|
||||
_, err = client.RunResourceAction(t.Context(), &applicationpkg.ResourceActionRunRequest{
|
||||
_, err = client.RunResourceActionV2(t.Context(), &applicationpkg.ResourceActionRunRequestV2{
|
||||
Name: &app.Name,
|
||||
Group: ptr.To("apps"),
|
||||
Kind: ptr.To("Deployment"),
|
||||
@@ -1076,7 +1076,7 @@ func assertNSResourceActions(t *testing.T, appName string, successful bool) {
|
||||
})
|
||||
assertError(err, expectedError)
|
||||
|
||||
_, err = cdClient.RunResourceAction(t.Context(), &applicationpkg.ResourceActionRunRequest{
|
||||
_, err = cdClient.RunResourceActionV2(t.Context(), &applicationpkg.ResourceActionRunRequestV2{
|
||||
Name: &appName,
|
||||
AppNamespace: ptr.To(fixture.AppNamespace()),
|
||||
ResourceName: ptr.To("guestbook-ui"),
|
||||
|
||||
@@ -1086,7 +1086,7 @@ func TestOldStyleResourceAction(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, []*ResourceAction{{Name: "sample", Disabled: false}}, actions.Actions)
|
||||
|
||||
_, err = client.RunResourceAction(t.Context(), &applicationpkg.ResourceActionRunRequest{
|
||||
_, err = client.RunResourceActionV2(t.Context(), &applicationpkg.ResourceActionRunRequestV2{
|
||||
Name: &app.Name,
|
||||
Group: ptr.To("apps"),
|
||||
Kind: ptr.To("Deployment"),
|
||||
@@ -1192,7 +1192,7 @@ func TestNewStyleResourceActionPermitted(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, []*ResourceAction{{Name: "sample", Disabled: false}}, actions.Actions)
|
||||
|
||||
_, err = client.RunResourceAction(t.Context(), &applicationpkg.ResourceActionRunRequest{
|
||||
_, err = client.RunResourceActionV2(t.Context(), &applicationpkg.ResourceActionRunRequestV2{
|
||||
Name: &app.Name,
|
||||
Group: ptr.To("batch"),
|
||||
Kind: ptr.To("CronJob"),
|
||||
@@ -1304,7 +1304,7 @@ func TestNewStyleResourceActionMixedOk(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, []*ResourceAction{{Name: "sample", Disabled: false}}, actions.Actions)
|
||||
|
||||
_, err = client.RunResourceAction(t.Context(), &applicationpkg.ResourceActionRunRequest{
|
||||
_, err = client.RunResourceActionV2(t.Context(), &applicationpkg.ResourceActionRunRequestV2{
|
||||
Name: &app.Name,
|
||||
Group: ptr.To("batch"),
|
||||
Kind: ptr.To("CronJob"),
|
||||
@@ -1507,7 +1507,7 @@ func assertResourceActions(t *testing.T, appName string, successful bool) {
|
||||
})
|
||||
assertError(err, expectedError)
|
||||
|
||||
_, err = cdClient.RunResourceAction(t.Context(), &applicationpkg.ResourceActionRunRequest{
|
||||
_, err = cdClient.RunResourceActionV2(t.Context(), &applicationpkg.ResourceActionRunRequestV2{
|
||||
Name: &appName,
|
||||
ResourceName: ptr.To("guestbook-ui"),
|
||||
Namespace: ptr.To(fixture.DeploymentNamespace()),
|
||||
|
||||
@@ -347,7 +347,7 @@ export class ApplicationsService {
|
||||
resourceActionParameters: models.ResourceActionParam[]
|
||||
): Promise<models.ResourceAction[]> {
|
||||
return requests
|
||||
.post(`/applications/${name}/resource/actions`)
|
||||
.post(`/applications/${name}/resource/actions/v2`)
|
||||
.send(
|
||||
JSON.stringify({
|
||||
appNamespace,
|
||||
@@ -547,7 +547,7 @@ export class ApplicationsService {
|
||||
public async getApplicationSet(name: string, namespace: string): Promise<models.ApplicationSet> {
|
||||
return requests
|
||||
.get(`/applicationsets/${name}`)
|
||||
.query({namespace})
|
||||
.query({appsetNamespace: namespace})
|
||||
.then(res => res.body as models.ApplicationSet);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -790,7 +790,7 @@ func (m *nativeGitClient) RevisionMetadata(revision string) (*RevisionMetadata,
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to interpret trailers for revision %q in repo %q: %w", revision, m.repoURL, err)
|
||||
}
|
||||
relatedCommits := getReferences(log.WithFields(log.Fields{"repo": m.repoURL, "revision": revision}), out)
|
||||
relatedCommits, _ := GetReferences(log.WithFields(log.Fields{"repo": m.repoURL, "revision": revision}), out)
|
||||
|
||||
out, err = m.runCmd("tag", "--points-at", revision)
|
||||
if err != nil {
|
||||
@@ -816,65 +816,23 @@ func truncate(str string) string {
|
||||
|
||||
var shaRegex = regexp.MustCompile(`^[0-9a-f]{5,40}$`)
|
||||
|
||||
// getReferences extracts related commit metadata from the commit message trailers. If referenced commit
|
||||
// GetReferences extracts related commit metadata from the commit message trailers. If referenced commit
|
||||
// metadata is present, we return a slice containing a single metadata object. If no related commit metadata is found,
|
||||
// we return a nil slice.
|
||||
//
|
||||
// If a trailer fails validation, we log an error and skip that trailer. We truncate the trailer values to 100
|
||||
// characters to avoid excessively long log messages.
|
||||
func getReferences(logCtx *log.Entry, commitMessageBody string) []RevisionReference {
|
||||
//
|
||||
// We also return the commit message body with all valid Argocd-reference-commit-* trailers removed.
|
||||
func GetReferences(logCtx *log.Entry, commitMessageBody string) ([]RevisionReference, string) {
|
||||
unrelatedLines := strings.Builder{}
|
||||
var relatedCommit CommitMetadata
|
||||
scanner := bufio.NewScanner(strings.NewReader(commitMessageBody))
|
||||
for scanner.Scan() {
|
||||
line := scanner.Text()
|
||||
if !strings.HasPrefix(line, "Argocd-reference-commit-") {
|
||||
continue
|
||||
}
|
||||
parts := strings.SplitN(line, ": ", 2)
|
||||
if len(parts) != 2 {
|
||||
continue
|
||||
}
|
||||
trailerKey := parts[0]
|
||||
trailerValue := parts[1]
|
||||
switch trailerKey {
|
||||
case "Argocd-reference-commit-repourl":
|
||||
_, err := url.Parse(trailerValue)
|
||||
if err != nil {
|
||||
logCtx.Errorf("failed to parse repo URL %q: %v", truncate(trailerValue), err)
|
||||
continue
|
||||
}
|
||||
relatedCommit.RepoURL = trailerValue
|
||||
case "Argocd-reference-commit-author":
|
||||
address, err := mail.ParseAddress(trailerValue)
|
||||
if err != nil || address == nil {
|
||||
logCtx.Errorf("failed to parse author email %q: %v", truncate(trailerValue), err)
|
||||
continue
|
||||
}
|
||||
relatedCommit.Author = *address
|
||||
case "Argocd-reference-commit-date":
|
||||
// Validate that it's the correct date format.
|
||||
t, err := time.Parse(time.RFC3339, trailerValue)
|
||||
if err != nil {
|
||||
logCtx.Errorf("failed to parse date %q with RFC3339 format: %v", truncate(trailerValue), err)
|
||||
continue
|
||||
}
|
||||
relatedCommit.Date = t.Format(time.RFC3339)
|
||||
case "Argocd-reference-commit-subject":
|
||||
relatedCommit.Subject = trailerValue
|
||||
case "Argocd-reference-commit-body":
|
||||
body := ""
|
||||
err := json.Unmarshal([]byte(trailerValue), &body)
|
||||
if err != nil {
|
||||
logCtx.Errorf("failed to parse body %q as JSON: %v", truncate(trailerValue), err)
|
||||
continue
|
||||
}
|
||||
relatedCommit.Body = body
|
||||
case "Argocd-reference-commit-sha":
|
||||
if !shaRegex.MatchString(trailerValue) {
|
||||
logCtx.Errorf("invalid commit SHA %q in trailer %s: must be a lowercase hex string 5-40 characters long", truncate(trailerValue), trailerKey)
|
||||
continue
|
||||
}
|
||||
relatedCommit.SHA = trailerValue
|
||||
updated := updateCommitMetadata(logCtx, &relatedCommit, line)
|
||||
if !updated {
|
||||
unrelatedLines.WriteString(line + "\n")
|
||||
}
|
||||
}
|
||||
var relatedCommits []RevisionReference
|
||||
@@ -883,7 +841,64 @@ func getReferences(logCtx *log.Entry, commitMessageBody string) []RevisionRefere
|
||||
Commit: &relatedCommit,
|
||||
})
|
||||
}
|
||||
return relatedCommits
|
||||
return relatedCommits, unrelatedLines.String()
|
||||
}
|
||||
|
||||
// updateCommitMetadata checks if the line is a valid Argocd-reference-commit-* trailer. If so, it updates
|
||||
// the relatedCommit object and returns true. If the line is not a valid trailer, it returns false.
|
||||
func updateCommitMetadata(logCtx *log.Entry, relatedCommit *CommitMetadata, line string) bool {
|
||||
if !strings.HasPrefix(line, "Argocd-reference-commit-") {
|
||||
return false
|
||||
}
|
||||
parts := strings.SplitN(line, ": ", 2)
|
||||
if len(parts) != 2 {
|
||||
return false
|
||||
}
|
||||
trailerKey := parts[0]
|
||||
trailerValue := parts[1]
|
||||
switch trailerKey {
|
||||
case "Argocd-reference-commit-repourl":
|
||||
_, err := url.Parse(trailerValue)
|
||||
if err != nil {
|
||||
logCtx.Errorf("failed to parse repo URL %q: %v", truncate(trailerValue), err)
|
||||
return false
|
||||
}
|
||||
relatedCommit.RepoURL = trailerValue
|
||||
case "Argocd-reference-commit-author":
|
||||
address, err := mail.ParseAddress(trailerValue)
|
||||
if err != nil || address == nil {
|
||||
logCtx.Errorf("failed to parse author email %q: %v", truncate(trailerValue), err)
|
||||
return false
|
||||
}
|
||||
relatedCommit.Author = *address
|
||||
case "Argocd-reference-commit-date":
|
||||
// Validate that it's the correct date format.
|
||||
t, err := time.Parse(time.RFC3339, trailerValue)
|
||||
if err != nil {
|
||||
logCtx.Errorf("failed to parse date %q with RFC3339 format: %v", truncate(trailerValue), err)
|
||||
return false
|
||||
}
|
||||
relatedCommit.Date = t.Format(time.RFC3339)
|
||||
case "Argocd-reference-commit-subject":
|
||||
relatedCommit.Subject = trailerValue
|
||||
case "Argocd-reference-commit-body":
|
||||
body := ""
|
||||
err := json.Unmarshal([]byte(trailerValue), &body)
|
||||
if err != nil {
|
||||
logCtx.Errorf("failed to parse body %q as JSON: %v", truncate(trailerValue), err)
|
||||
return false
|
||||
}
|
||||
relatedCommit.Body = body
|
||||
case "Argocd-reference-commit-sha":
|
||||
if !shaRegex.MatchString(trailerValue) {
|
||||
logCtx.Errorf("invalid commit SHA %q in trailer %s: must be a lowercase hex string 5-40 characters long", truncate(trailerValue), trailerKey)
|
||||
return false
|
||||
}
|
||||
relatedCommit.SHA = trailerValue
|
||||
default:
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// VerifyCommitSignature Runs verify-commit on a given revision and returns the output
|
||||
|
||||
@@ -1103,20 +1103,22 @@ func (m *mockCreds) GetUserInfo(_ context.Context) (string, string, error) {
|
||||
return "", "", nil
|
||||
}
|
||||
|
||||
func Test_getReferences(t *testing.T) {
|
||||
func Test_GetReferences(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
now := time.Now()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
input string
|
||||
expected []RevisionReference
|
||||
name string
|
||||
input string
|
||||
expectedReferences []RevisionReference
|
||||
expectedMessage string
|
||||
}{
|
||||
{
|
||||
name: "No trailers",
|
||||
input: "This is a commit message without trailers.",
|
||||
expected: nil,
|
||||
name: "No trailers",
|
||||
input: "This is a commit message without trailers.",
|
||||
expectedReferences: nil,
|
||||
expectedMessage: "This is a commit message without trailers.\n",
|
||||
},
|
||||
{
|
||||
name: "Invalid trailers",
|
||||
@@ -1126,25 +1128,36 @@ Argocd-reference-commit-sha: xyz123
|
||||
Argocd-reference-commit-body: this isn't json
|
||||
Argocd-reference-commit-author: % not email %
|
||||
Argocd-reference-commit-bogus:`,
|
||||
expected: nil,
|
||||
expectedReferences: nil,
|
||||
expectedMessage: `Argocd-reference-commit-repourl: % invalid %
|
||||
Argocd-reference-commit-date: invalid-date
|
||||
Argocd-reference-commit-sha: xyz123
|
||||
Argocd-reference-commit-body: this isn't json
|
||||
Argocd-reference-commit-author: % not email %
|
||||
Argocd-reference-commit-bogus:
|
||||
`,
|
||||
},
|
||||
{
|
||||
name: "Unknown trailers",
|
||||
input: "Argocd-reference-commit-unknown: foobar",
|
||||
expected: nil,
|
||||
name: "Unknown trailers",
|
||||
input: "Argocd-reference-commit-unknown: foobar",
|
||||
expectedReferences: nil,
|
||||
expectedMessage: "Argocd-reference-commit-unknown: foobar\n",
|
||||
},
|
||||
{
|
||||
name: "Some valid and Invalid trailers",
|
||||
input: `Argocd-reference-commit-sha: abc123
|
||||
Argocd-reference-commit-repourl: % invalid %
|
||||
Argocd-reference-commit-date: invalid-date`,
|
||||
expected: []RevisionReference{
|
||||
expectedReferences: []RevisionReference{
|
||||
{
|
||||
Commit: &CommitMetadata{
|
||||
SHA: "abc123",
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedMessage: `Argocd-reference-commit-repourl: % invalid %
|
||||
Argocd-reference-commit-date: invalid-date
|
||||
`,
|
||||
},
|
||||
{
|
||||
name: "Valid trailers",
|
||||
@@ -1154,7 +1167,7 @@ Argocd-reference-commit-date: %s
|
||||
Argocd-reference-commit-subject: Fix bug
|
||||
Argocd-reference-commit-body: "Fix bug\n\nSome: trailer"
|
||||
Argocd-reference-commit-sha: abc123`, now.Format(time.RFC3339)),
|
||||
expected: []RevisionReference{
|
||||
expectedReferences: []RevisionReference{
|
||||
{
|
||||
Commit: &CommitMetadata{
|
||||
Author: mail.Address{
|
||||
@@ -1169,18 +1182,20 @@ Argocd-reference-commit-sha: abc123`, now.Format(time.RFC3339)),
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedMessage: "",
|
||||
},
|
||||
{
|
||||
name: "Duplicate trailers",
|
||||
input: `Argocd-reference-commit-repourl: https://github.com/org/repo.git
|
||||
Argocd-reference-commit-repourl: https://github.com/another/repo.git`,
|
||||
expected: []RevisionReference{
|
||||
expectedReferences: []RevisionReference{
|
||||
{
|
||||
Commit: &CommitMetadata{
|
||||
RepoURL: "https://github.com/another/repo.git",
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedMessage: "",
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1189,8 +1204,9 @@ Argocd-reference-commit-repourl: https://github.com/another/repo.git`,
|
||||
t.Parallel()
|
||||
|
||||
logCtx := log.WithFields(log.Fields{})
|
||||
result := getReferences(logCtx, tt.input)
|
||||
assert.Equal(t, tt.expected, result)
|
||||
result, message := GetReferences(logCtx, tt.input)
|
||||
assert.Equal(t, tt.expectedReferences, result)
|
||||
assert.Equal(t, tt.expectedMessage, message)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,8 @@ import (
|
||||
"github.com/Masterminds/semver/v3"
|
||||
"sigs.k8s.io/yaml"
|
||||
|
||||
"github.com/argoproj/argo-cd/v3/util/io"
|
||||
|
||||
"github.com/argoproj/gitops-engine/pkg/utils/kube"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
@@ -24,8 +26,6 @@ import (
|
||||
executil "github.com/argoproj/argo-cd/v3/util/exec"
|
||||
"github.com/argoproj/argo-cd/v3/util/git"
|
||||
"github.com/argoproj/argo-cd/v3/util/proxy"
|
||||
|
||||
securejoin "github.com/cyphar/filepath-securejoin"
|
||||
)
|
||||
|
||||
// Image represents a Docker image in the format NAME[:TAG].
|
||||
@@ -346,12 +346,18 @@ func (k *kustomize) Build(opts *v1alpha1.ApplicationSourceKustomize, kustomizeOp
|
||||
foundComponents := opts.Components
|
||||
if opts.IgnoreMissingComponents {
|
||||
foundComponents = make([]string, 0)
|
||||
root, err := os.OpenRoot(k.repoRoot)
|
||||
defer io.Close(root)
|
||||
if err != nil {
|
||||
return nil, nil, nil, fmt.Errorf("failed to open the repo folder: %w", err)
|
||||
}
|
||||
|
||||
for _, c := range opts.Components {
|
||||
resolvedPath, err := securejoin.SecureJoin(k.path, c)
|
||||
resolvedPath, err := filepath.Rel(k.repoRoot, filepath.Join(k.path, c))
|
||||
if err != nil {
|
||||
return nil, nil, nil, fmt.Errorf("Kustomize components path failed: %w", err)
|
||||
return nil, nil, nil, fmt.Errorf("kustomize components path failed: %w", err)
|
||||
}
|
||||
_, err = os.Stat(resolvedPath)
|
||||
_, err = root.Stat(resolvedPath)
|
||||
if err != nil {
|
||||
log.Debugf("%s component directory does not exist", resolvedPath)
|
||||
continue
|
||||
|
||||
@@ -25,6 +25,7 @@ const (
|
||||
kustomization6 = "kustomization_yaml_components"
|
||||
kustomization7 = "label_without_selector"
|
||||
kustomization8 = "kustomization_yaml_patches_empty"
|
||||
kustomization9 = "kustomization_yaml_components_monorepo"
|
||||
)
|
||||
|
||||
func testDataDir(tb testing.TB, testData string) (string, error) {
|
||||
@@ -512,6 +513,31 @@ func TestKustomizeBuildComponents(t *testing.T) {
|
||||
assert.Equal(t, int64(3), replicas)
|
||||
}
|
||||
|
||||
func TestKustomizeBuildComponentsMonoRepo(t *testing.T) {
|
||||
rootPath, err := testDataDir(t, kustomization9)
|
||||
require.NoError(t, err)
|
||||
appPath := path.Join(rootPath, "envs/inseng-pdx-egert-sandbox/namespaces/inst-system/apps/hello-world")
|
||||
kustomize := NewKustomizeApp(rootPath, appPath, git.NopCreds{}, "", "", "", "")
|
||||
kustomizeSource := v1alpha1.ApplicationSourceKustomize{
|
||||
Components: []string{"../../../../../../kustomize/components/all"},
|
||||
IgnoreMissingComponents: true,
|
||||
}
|
||||
objs, _, _, err := kustomize.Build(&kustomizeSource, nil, nil, nil)
|
||||
require.NoError(t, err)
|
||||
obj := objs[2]
|
||||
require.Equal(t, "hello-world-kustomize", obj.GetName())
|
||||
require.Equal(t, map[string]string{
|
||||
"app.kubernetes.io/name": "hello-world-kustomize",
|
||||
"app.kubernetes.io/owner": "fire-team",
|
||||
}, obj.GetLabels())
|
||||
replicas, ok, err := unstructured.NestedSlice(obj.Object, "spec", "template", "spec", "tolerations")
|
||||
require.NoError(t, err)
|
||||
require.True(t, ok)
|
||||
require.Len(t, replicas, 1)
|
||||
require.Equal(t, "my-special-toleration", replicas[0].(map[string]any)["key"])
|
||||
require.Equal(t, "Exists", replicas[0].(map[string]any)["operator"])
|
||||
}
|
||||
|
||||
func TestKustomizeBuildPatches(t *testing.T) {
|
||||
appPath, err := testDataDir(t, kustomization5)
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
---
|
||||
kustomize:
|
||||
componentsPath: ../../../../../../kustomize/components
|
||||
@@ -0,0 +1,33 @@
|
||||
---
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
|
||||
# All the members of this group are meant be populated from the
|
||||
# same nonproduction overlay of the matching app
|
||||
resources:
|
||||
- ../../../../../../kustomize/apps/hello-world/base
|
||||
|
||||
nameSuffix: -kustomize
|
||||
|
||||
labels:
|
||||
- pairs:
|
||||
app.kubernetes.io/name: hello-world-kustomize
|
||||
includeSelectors: true
|
||||
includeTemplates: true
|
||||
|
||||
patches:
|
||||
# Adjusting the serviceAccount ref
|
||||
- patch: |-
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: hello-world
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
serviceAccountName: hello-world-kustomize
|
||||
|
||||
# Container image versions across the members
|
||||
images:
|
||||
- name: hello-world
|
||||
newTag: 1.17.0
|
||||
@@ -0,0 +1,34 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: hello-world
|
||||
labels:
|
||||
app.kubernetes.io/name: hello-world
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: hello-world
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/name: hello-world
|
||||
spec:
|
||||
serviceAccountName: hello-world
|
||||
containers:
|
||||
- name: hello-world
|
||||
image: "nginx:1.16.0"
|
||||
imagePullPolicy: IfNotPresent
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: 80
|
||||
protocol: TCP
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /
|
||||
port: http
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /
|
||||
port: http
|
||||
tolerations: []
|
||||
@@ -0,0 +1,8 @@
|
||||
---
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
|
||||
resources:
|
||||
- deployment.yaml
|
||||
- service.yaml
|
||||
- serviceaccount.yaml
|
||||
@@ -0,0 +1,16 @@
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: hello-world
|
||||
labels:
|
||||
app.kubernetes.io/name: hello-world
|
||||
spec:
|
||||
type: ClusterIP
|
||||
ports:
|
||||
- port: 80
|
||||
targetPort: http
|
||||
protocol: TCP
|
||||
name: http
|
||||
selector:
|
||||
app.kubernetes.io/name: hello-world
|
||||
@@ -0,0 +1,7 @@
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: hello-world
|
||||
labels:
|
||||
app.kubernetes.io/name: hello-world
|
||||
@@ -0,0 +1,19 @@
|
||||
---
|
||||
apiVersion: kustomize.config.k8s.io/v1alpha1
|
||||
kind: Component
|
||||
|
||||
labels:
|
||||
- pairs:
|
||||
app.kubernetes.io/owner: fire-team
|
||||
includeSelectors: false
|
||||
includeTemplates: false
|
||||
|
||||
patches:
|
||||
- target:
|
||||
kind: Deployment
|
||||
patch: |-
|
||||
- op: add
|
||||
path: /spec/template/spec/tolerations/-
|
||||
value:
|
||||
key: my-special-toleration
|
||||
operator: Exists
|
||||
@@ -295,6 +295,11 @@ func (c *nativeOCIClient) DigestMetadata(ctx context.Context, digest string) (*i
|
||||
func (c *nativeOCIClient) ResolveRevision(ctx context.Context, revision string, noCache bool) (string, error) {
|
||||
digest, err := c.resolveDigest(ctx, revision) // Lookup explicit revision
|
||||
if err != nil {
|
||||
// If the revision is not a semver constraint, just return the error
|
||||
if !versions.IsConstraint(revision) {
|
||||
return digest, err
|
||||
}
|
||||
|
||||
tags, err := c.GetTags(ctx, noCache)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("error fetching tags: %w", err)
|
||||
|
||||
@@ -374,7 +374,7 @@ func Test_nativeOCIClient_ResolveRevision(t *testing.T) {
|
||||
fields: fields{repo: store, tagsFunc: func(context.Context, string) (tags []string, err error) {
|
||||
return []string{"1.0.0", "1.1.0", "1.2.0", "2.0.0"}, nil
|
||||
}},
|
||||
expectedError: errors.New("no version for constraints: failed to determine semver constraint: improper constraint: sha256:abc123"),
|
||||
expectedError: errors.New("cannot get digest for revision sha256:abc123: sha256:abc123: not found"),
|
||||
},
|
||||
{
|
||||
name: "resolve latest tag",
|
||||
|
||||
@@ -62,3 +62,12 @@ func MaxVersion(revision string, tags []string) (string, error) {
|
||||
log.Debugf("Semver constraint '%s' resolved to version '%s'", constraints.String(), maxVersion.Original())
|
||||
return maxVersion.Original(), nil
|
||||
}
|
||||
|
||||
// Returns true if the given revision is not an exact semver and can be parsed as a semver constraint
|
||||
func IsConstraint(revision string) bool {
|
||||
if _, err := semver.NewVersion(revision); err == nil {
|
||||
return false
|
||||
}
|
||||
_, err := semver.NewConstraint(revision)
|
||||
return err == nil
|
||||
}
|
||||
|
||||
@@ -65,3 +65,27 @@ func TestTags_MaxVersion(t *testing.T) {
|
||||
require.Error(t, err)
|
||||
})
|
||||
}
|
||||
|
||||
func TestTags_IsConstraint(t *testing.T) {
|
||||
t.Run("Exact", func(t *testing.T) {
|
||||
assert.False(t, IsConstraint("0.5.3"))
|
||||
})
|
||||
t.Run("Exact nonsemver", func(t *testing.T) {
|
||||
assert.False(t, IsConstraint("2024.03-LTS-RC19"))
|
||||
})
|
||||
t.Run("Constraint", func(t *testing.T) {
|
||||
assert.True(t, IsConstraint("= 0.5.3"))
|
||||
})
|
||||
t.Run("Constraint", func(t *testing.T) {
|
||||
assert.True(t, IsConstraint("> 0.5.3"))
|
||||
})
|
||||
t.Run("Constraint", func(t *testing.T) {
|
||||
assert.True(t, IsConstraint(">0.5.0,<0.7.0"))
|
||||
})
|
||||
t.Run("Constraint", func(t *testing.T) {
|
||||
assert.True(t, IsConstraint("0.7.*"))
|
||||
})
|
||||
t.Run("Constraint", func(t *testing.T) {
|
||||
assert.True(t, IsConstraint("*"))
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,12 +1,7 @@
|
||||
package workloadidentity
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -22,34 +17,9 @@ type TokenProvider interface {
|
||||
GetToken(scope string) (*Token, error)
|
||||
}
|
||||
|
||||
type WorkloadIdentityTokenProvider struct {
|
||||
tokenCredential azcore.TokenCredential
|
||||
}
|
||||
|
||||
// Used to propagate initialization error if any
|
||||
var initError error
|
||||
|
||||
func NewWorkloadIdentityTokenProvider() TokenProvider {
|
||||
cred, err := azidentity.NewDefaultAzureCredential(&azidentity.DefaultAzureCredentialOptions{})
|
||||
initError = err
|
||||
return WorkloadIdentityTokenProvider{tokenCredential: cred}
|
||||
}
|
||||
|
||||
func (c WorkloadIdentityTokenProvider) GetToken(scope string) (*Token, error) {
|
||||
if initError != nil {
|
||||
return nil, initError
|
||||
}
|
||||
|
||||
token, err := c.tokenCredential.GetToken(context.Background(), policy.TokenRequestOptions{
|
||||
Scopes: []string{scope},
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &Token{AccessToken: token.Token, ExpiresOn: token.ExpiresOn}, nil
|
||||
}
|
||||
|
||||
func CalculateCacheExpiryBasedOnTokenExpiry(tokenExpiry time.Time) time.Duration {
|
||||
// Calculate the cache expiry as 5 minutes before the token expires
|
||||
cacheExpiry := time.Until(tokenExpiry) - time.Minute*5
|
||||
|
||||
36
util/workloadidentity/workloadidentity_cgo.go
Normal file
36
util/workloadidentity/workloadidentity_cgo.go
Normal file
@@ -0,0 +1,36 @@
|
||||
//go:build !darwin || (cgo && darwin)
|
||||
|
||||
package workloadidentity
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
|
||||
)
|
||||
|
||||
type WorkloadIdentityTokenProvider struct {
|
||||
tokenCredential azcore.TokenCredential
|
||||
}
|
||||
|
||||
func NewWorkloadIdentityTokenProvider() TokenProvider {
|
||||
cred, err := azidentity.NewDefaultAzureCredential(&azidentity.DefaultAzureCredentialOptions{})
|
||||
initError = err
|
||||
return WorkloadIdentityTokenProvider{tokenCredential: cred}
|
||||
}
|
||||
|
||||
func (c WorkloadIdentityTokenProvider) GetToken(scope string) (*Token, error) {
|
||||
if initError != nil {
|
||||
return nil, initError
|
||||
}
|
||||
|
||||
token, err := c.tokenCredential.GetToken(context.Background(), policy.TokenRequestOptions{
|
||||
Scopes: []string{scope},
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &Token{AccessToken: token.Token, ExpiresOn: token.ExpiresOn}, nil
|
||||
}
|
||||
25
util/workloadidentity/workloadidentity_no_cgo.go
Normal file
25
util/workloadidentity/workloadidentity_no_cgo.go
Normal file
@@ -0,0 +1,25 @@
|
||||
//go:build darwin && !cgo
|
||||
|
||||
// Package workloadidentity
|
||||
// This file is used when the GOOS is darwin and CGO is not enabled.
|
||||
// It provides a no-op implementation of the WorkloadIdentityTokenProvider to allow goreleaser to build
|
||||
// a darwin binary on a linux machine.
|
||||
package workloadidentity
|
||||
|
||||
import (
|
||||
"errors"
|
||||
)
|
||||
|
||||
type WorkloadIdentityTokenProvider struct {
|
||||
}
|
||||
|
||||
const CGOError = "CGO is not enabled, cannot use workload identity token provider"
|
||||
|
||||
// Code that does not require CGO
|
||||
func NewWorkloadIdentityTokenProvider() TokenProvider {
|
||||
panic(CGOError)
|
||||
}
|
||||
|
||||
func (c WorkloadIdentityTokenProvider) GetToken(scope string) (*Token, error) {
|
||||
return nil, errors.New(CGOError)
|
||||
}
|
||||
Reference in New Issue
Block a user