Compare commits

...

20 Commits

Author SHA1 Message Date
github-actions[bot]
20fd621aa2 Bump version to 2.11.0-rc3 (#18019)
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: pasha-codefresh <39732895+pasha-codefresh@users.noreply.github.com>
2024-04-29 22:56:02 +03:00
Ishita Sequeira
f875931992 feat(cli): add support for multiple sources to sync command (#18016)
* update sync command

Signed-off-by: ishitasequeira <ishiseq29@gmail.com>

use arrays instead of map to display ApplicationManifetQuery fields in swagger

Signed-off-by: ishitasequeira <ishiseq29@gmail.com>

rebase and update logic for sync command

Signed-off-by: ishitasequeira <ishiseq29@gmail.com>

update conditions

Signed-off-by: ishitasequeira <ishiseq29@gmail.com>

update displayRevisions on OperationState

Signed-off-by: ishitasequeira <ishiseq29@gmail.com>

remove rerunreport file

Signed-off-by: ishitasequeira <ishiseq29@gmail.com>

fix index 0 out of bounds error

Signed-off-by: ishitasequeira <ishiseq29@gmail.com>

Address comments

Signed-off-by: ishitasequeira <ishiseq29@gmail.com>

fix codegen

Signed-off-by: ishitasequeira <ishiseq29@gmail.com>

rename GetSourcePtrBySourceIndex to GetSourcePtrByIndex

Signed-off-by: ishitasequeira <ishiseq29@gmail.com>

rename GetSourcePtrBySourcePosition to GetSourcePtrByPosition

Signed-off-by: ishitasequeira <ishiseq29@gmail.com>

rebase with master and resolve conflicts

Signed-off-by: ishitasequeira <ishiseq29@gmail.com>

fix codegen

Signed-off-by: ishitasequeira <ishiseq29@gmail.com>

Address feedback and add tests

Signed-off-by: ishitasequeira <ishiseq29@gmail.com>

fix unit test

Signed-off-by: ishitasequeira <ishiseq29@gmail.com>

* codegen post cherry-pick

Signed-off-by: ishitasequeira <ishiseq29@gmail.com>

---------

Signed-off-by: ishitasequeira <ishiseq29@gmail.com>
2024-04-29 22:34:01 +03:00
pasha-codefresh
e1f890d176 feat: update notifications (#18017)
Signed-off-by: pashakostohrys <pavel@codefresh.io>
Co-authored-by: Lukas Aldershaab <lpjoergensen@gmail.com>
2024-04-29 11:42:19 -04:00
gcp-cherry-pick-bot[bot]
602f5445b1 Fix post-delete finalizer in appset (#18003) (#18005)
Signed-off-by: Joe Bowbeer <joe.bowbeer@gmail.com>
Co-authored-by: Joe Bowbeer <joe.bowbeer@gmail.com>
2024-04-26 16:47:48 -07:00
pasha-codefresh
617f8a414f fix: codegen after security fix (#17987)
Signed-off-by: pashakostohrys <pavel@codefresh.io>
2024-04-26 16:24:54 +03:00
pasha-codefresh
0460b9873e Merge pull request from GHSA-9m6p-x4h2-6frq
* feat: limit jq.Run with timeout

Signed-off-by: pashakostohrys <pavel@codefresh.io>

* feat: ignore normalizer jq execution timeout as env variable

Signed-off-by: pashakostohrys <pavel@codefresh.io>

* feat: customize error message and add doc section

Signed-off-by: pashakostohrys <pavel@codefresh.io>

* feat: improve log and change a way how to get variable

Signed-off-by: pashakostohrys <pavel@codefresh.io>

* chore: fix import`s order

Signed-off-by: pashakostohrys <pavel@codefresh.io>

* chore: rename variable inside sts

Signed-off-by: pashakostohrys <pavel@codefresh.io>

* chore: fix import order

Signed-off-by: pashakostohrys <pavel@codefresh.io>

---------

Signed-off-by: pashakostohrys <pavel@codefresh.io>
2024-04-26 12:24:32 +03:00
pasha-codefresh
25c6653d8a Merge pull request from GHSA-9m6p-x4h2-6frq
* feat: limit jq.Run with timeout

Signed-off-by: pashakostohrys <pavel@codefresh.io>

* feat: ignore normalizer jq execution timeout as env variable

Signed-off-by: pashakostohrys <pavel@codefresh.io>

* feat: customize error message and add doc section

Signed-off-by: pashakostohrys <pavel@codefresh.io>

* feat: improve log and change a way how to get variable

Signed-off-by: pashakostohrys <pavel@codefresh.io>

* chore: fix import`s order

Signed-off-by: pashakostohrys <pavel@codefresh.io>

* chore: rename variable inside sts

Signed-off-by: pashakostohrys <pavel@codefresh.io>

* chore: fix import order

Signed-off-by: pashakostohrys <pavel@codefresh.io>

---------

Signed-off-by: pashakostohrys <pavel@codefresh.io>
2024-04-26 12:24:02 +03:00
gcp-cherry-pick-bot[bot]
9f186dab30 fix: use cmp vs reflect.DeepEqual for comparing Applications (#17861) (#17940) (#17958)
* fix(compare): appset compare the child apps with cmp vs reflect



* remove debug lines



* remove debug lines



---------

Signed-off-by: rumstead <37445536+rumstead@users.noreply.github.com>
Co-authored-by: rumstead <37445536+rumstead@users.noreply.github.com>
2024-04-24 16:21:05 -04:00
gcp-cherry-pick-bot[bot]
fb573e0008 docs: Mention configmap to enable new git file globbing by name (#17936) (#17938)
Signed-off-by: Christian Ciach <christian.ciach@gmail.com>
Co-authored-by: ChristianCiach <christian.ciach@gmail.com>
2024-04-23 09:41:05 -04:00
gcp-cherry-pick-bot[bot]
35a2ebe428 docs(cli): remove docs for non-existing argocd admin commands (#17924) (#17925)
Co-authored-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
2024-04-22 12:32:13 -04:00
gcp-cherry-pick-bot[bot]
3bb7ac92e8 remove mention of beta state from apps-in-any-namespace doc (#17896) (#17899)
Signed-off-by: ishitasequeira <ishiseq29@gmail.com>
Co-authored-by: Ishita Sequeira <46771830+ishitasequeira@users.noreply.github.com>
2024-04-19 14:04:34 +03:00
Amit Lin
2ef8fe2246 fix: debian source typo in Dockerfile (#17886)
Signed-off-by: Amit Lin <amitlin.dev@gmail.com>
2024-04-18 10:19:28 -04:00
gcp-cherry-pick-bot[bot]
ce0e3bc7f0 fix: invalid revision in re-used manifest cache (#17874) (#17877)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
Co-authored-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2024-04-18 10:50:19 +03:00
gcp-cherry-pick-bot[bot]
29cdd31572 fix(api): respect all allowed audiences, regardless of check order (#17876) (#17878)
Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
Co-authored-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
2024-04-17 21:12:13 -04:00
github-actions[bot]
24ef7775e7 Bump version to 2.11.0-rc2 (#17852)
Signed-off-by: GitHub <noreply@github.com>
Co-authored-by: pasha-codefresh <pasha-codefresh@users.noreply.github.com>
2024-04-15 22:40:31 +03:00
pasha-codefresh
b71f0c8b54 fix: codegen and e2e tests (#17851)
Signed-off-by: pashakostohrys <pavel@codefresh.io>
2024-04-15 22:35:51 +03:00
pasha-codefresh
edcf167be8 Merge pull request from GHSA-2gvw-w6fj-7m3c
* sec: validate a project before execute an action

Signed-off-by: pashakostohrys <pavel@codefresh.io>

* sec: validate a project before execute an action

Signed-off-by: pashakostohrys <pavel@codefresh.io>

---------

Signed-off-by: pashakostohrys <pavel@codefresh.io>
2024-04-15 10:20:07 +03:00
gcp-cherry-pick-bot[bot]
be48990126 fix(api): use arrays instead of map to display ApplicationManifetQuery fields in swagger (#17804) (#17820)
* use arrays instead of map to display ApplicationManifetQuery fields in swagger



* fix equality conditions for souce-position check



---------

Signed-off-by: ishitasequeira <ishiseq29@gmail.com>
Co-authored-by: Ishita Sequeira <46771830+ishitasequeira@users.noreply.github.com>
2024-04-12 16:07:55 -04:00
gcp-cherry-pick-bot[bot]
9d5b17403f chore: rename source-indexes to source-positions (#17746) (#17753)
* chore: rename source-indexes to source-positions



* update documentation



---------

Signed-off-by: ishitasequeira <ishiseq29@gmail.com>
Co-authored-by: Ishita Sequeira <46771830+ishitasequeira@users.noreply.github.com>
2024-04-05 09:39:13 -04:00
github-actions[bot]
f491935eb9 Bump version to 2.11.0-rc1 (#17751)
Signed-off-by: GitHub <noreply@github.com>
Co-authored-by: pasha-codefresh <pasha-codefresh@users.noreply.github.com>
2024-04-05 15:08:37 +03:00
83 changed files with 2970 additions and 1947 deletions

View File

@@ -6,7 +6,7 @@ ARG BASE_IMAGE=docker.io/library/ubuntu:22.04@sha256:0bced47fffa3361afa981854fca
####################################################################################################
FROM docker.io/library/golang:1.21.9@sha256:7d0dcbe5807b1ad7272a598fbf9d7af15b5e2bed4fd6c4c2b5b3684df0b317dd AS builder
RUN echo 'deb http://deb.debian.org/debian buster-backports main' >> /etc/apt/sources.list
RUN echo 'deb http://archive.debian.org/debian buster-backports main' >> /etc/apt/sources.list
RUN apt-get update && apt-get install --no-install-recommends -y \
openssh-server \

View File

@@ -1 +1 @@
2.11.0
2.11.0-rc3

View File

@@ -17,9 +17,11 @@ package controllers
import (
"context"
"fmt"
"reflect"
"strings"
"time"
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
log "github.com/sirupsen/logrus"
corev1 "k8s.io/api/core/v1"
apierr "k8s.io/apimachinery/pkg/api/errors"
@@ -50,6 +52,7 @@ import (
argov1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1"
appclientset "github.com/argoproj/argo-cd/v2/pkg/client/clientset/versioned"
argoutil "github.com/argoproj/argo-cd/v2/util/argo"
"github.com/argoproj/argo-cd/v2/util/argo/normalizers"
"github.com/argoproj/argo-cd/v2/pkg/apis/application"
)
@@ -668,7 +671,7 @@ func (r *ApplicationSetReconciler) createOrUpdateInCluster(ctx context.Context,
},
}
action, err := utils.CreateOrUpdate(ctx, appLog, r.Client, applicationSet.Spec.IgnoreApplicationDifferences, found, func() error {
action, err := utils.CreateOrUpdate(ctx, appLog, r.Client, applicationSet.Spec.IgnoreApplicationDifferences, normalizers.IgnoreNormalizerOpts{}, found, func() error {
// Copy only the Application/ObjectMeta fields that are significant, from the generatedApp
found.Spec = generatedApp.Spec
@@ -716,6 +719,17 @@ func (r *ApplicationSetReconciler) createOrUpdateInCluster(ctx context.Context,
}
}
// Preserve post-delete finalizers:
// https://github.com/argoproj/argo-cd/issues/17181
for _, finalizer := range found.ObjectMeta.Finalizers {
if strings.HasPrefix(finalizer, argov1alpha1.PostDeleteFinalizerName) {
if generatedApp.Finalizers == nil {
generatedApp.Finalizers = []string{}
}
generatedApp.Finalizers = append(generatedApp.Finalizers, finalizer)
}
}
found.ObjectMeta.Annotations = generatedApp.Annotations
found.ObjectMeta.Finalizers = generatedApp.Finalizers
@@ -1528,10 +1542,14 @@ func shouldRequeueApplicationSet(appOld *argov1alpha1.Application, appNew *argov
}
// the applicationset controller owns the application spec, labels, annotations, and finalizers on the applications
if !reflect.DeepEqual(appOld.Spec, appNew.Spec) ||
!reflect.DeepEqual(appOld.ObjectMeta.GetAnnotations(), appNew.ObjectMeta.GetAnnotations()) ||
!reflect.DeepEqual(appOld.ObjectMeta.GetLabels(), appNew.ObjectMeta.GetLabels()) ||
!reflect.DeepEqual(appOld.ObjectMeta.GetFinalizers(), appNew.ObjectMeta.GetFinalizers()) {
// reflect.DeepEqual considers nil slices/maps not equal to empty slices/maps
// https://pkg.go.dev/reflect#DeepEqual
// ApplicationDestination has an unexported field so we can just use the == for comparsion
if !cmp.Equal(appOld.Spec, appNew.Spec, cmpopts.EquateEmpty(), cmpopts.EquateComparable(argov1alpha1.ApplicationDestination{})) ||
!cmp.Equal(appOld.ObjectMeta.GetAnnotations(), appNew.ObjectMeta.GetAnnotations(), cmpopts.EquateEmpty()) ||
!cmp.Equal(appOld.ObjectMeta.GetLabels(), appNew.ObjectMeta.GetLabels(), cmpopts.EquateEmpty()) ||
!cmp.Equal(appOld.ObjectMeta.GetFinalizers(), appNew.ObjectMeta.GetFinalizers(), cmpopts.EquateEmpty()) {
return true
}

View File

@@ -1281,6 +1281,71 @@ func TestCreateOrUpdateInCluster(t *testing.T) {
},
},
},
}, {
name: "Ensure that argocd post-delete finalizers are preserved from an existing app",
appSet: v1alpha1.ApplicationSet{
ObjectMeta: metav1.ObjectMeta{
Name: "name",
Namespace: "namespace",
},
Spec: v1alpha1.ApplicationSetSpec{
Template: v1alpha1.ApplicationSetTemplate{
Spec: v1alpha1.ApplicationSpec{
Project: "project",
},
},
},
},
existingApps: []v1alpha1.Application{
{
TypeMeta: metav1.TypeMeta{
Kind: application.ApplicationKind,
APIVersion: "argoproj.io/v1alpha1",
},
ObjectMeta: metav1.ObjectMeta{
Name: "app1",
Namespace: "namespace",
ResourceVersion: "2",
Finalizers: []string{
v1alpha1.PostDeleteFinalizerName,
v1alpha1.PostDeleteFinalizerName + "/mystage",
},
},
Spec: v1alpha1.ApplicationSpec{
Project: "project",
},
},
},
desiredApps: []v1alpha1.Application{
{
ObjectMeta: metav1.ObjectMeta{
Name: "app1",
},
Spec: v1alpha1.ApplicationSpec{
Project: "project",
},
},
},
expected: []v1alpha1.Application{
{
TypeMeta: metav1.TypeMeta{
Kind: application.ApplicationKind,
APIVersion: "argoproj.io/v1alpha1",
},
ObjectMeta: metav1.ObjectMeta{
Name: "app1",
Namespace: "namespace",
ResourceVersion: "2",
Finalizers: []string{
v1alpha1.PostDeleteFinalizerName,
v1alpha1.PostDeleteFinalizerName + "/mystage",
},
},
Spec: v1alpha1.ApplicationSpec{
Project: "project",
},
},
},
},
} {
@@ -6172,14 +6237,70 @@ func TestOwnsHandler(t *testing.T) {
ObjectOld: &v1alpha1.Application{ObjectMeta: metav1.ObjectMeta{Labels: map[string]string{"foo": "bar"}}},
ObjectNew: &v1alpha1.Application{ObjectMeta: metav1.ObjectMeta{Labels: map[string]string{"bar": "foo"}}},
}}, want: true},
{name: "DifferentApplicationLabelsNil", args: args{e: event.UpdateEvent{
ObjectOld: &v1alpha1.Application{ObjectMeta: metav1.ObjectMeta{Labels: map[string]string{}}},
ObjectNew: &v1alpha1.Application{ObjectMeta: metav1.ObjectMeta{Labels: nil}},
}}, want: false},
{name: "DifferentApplicationAnnotations", args: args{e: event.UpdateEvent{
ObjectOld: &v1alpha1.Application{ObjectMeta: metav1.ObjectMeta{Annotations: map[string]string{"foo": "bar"}}},
ObjectNew: &v1alpha1.Application{ObjectMeta: metav1.ObjectMeta{Annotations: map[string]string{"bar": "foo"}}},
}}, want: true},
{name: "DifferentApplicationAnnotationsNil", args: args{e: event.UpdateEvent{
ObjectOld: &v1alpha1.Application{ObjectMeta: metav1.ObjectMeta{Annotations: map[string]string{}}},
ObjectNew: &v1alpha1.Application{ObjectMeta: metav1.ObjectMeta{Annotations: nil}},
}}, want: false},
{name: "DifferentApplicationFinalizers", args: args{e: event.UpdateEvent{
ObjectOld: &v1alpha1.Application{ObjectMeta: metav1.ObjectMeta{Finalizers: []string{"argo"}}},
ObjectNew: &v1alpha1.Application{ObjectMeta: metav1.ObjectMeta{Finalizers: []string{"none"}}},
}}, want: true},
{name: "DifferentApplicationFinalizersNil", args: args{e: event.UpdateEvent{
ObjectOld: &v1alpha1.Application{ObjectMeta: metav1.ObjectMeta{Finalizers: []string{}}},
ObjectNew: &v1alpha1.Application{ObjectMeta: metav1.ObjectMeta{Finalizers: nil}},
}}, want: false},
{name: "ApplicationDestinationSame", args: args{e: event.UpdateEvent{
ObjectOld: &v1alpha1.Application{
Spec: v1alpha1.ApplicationSpec{
Destination: v1alpha1.ApplicationDestination{
Server: "server",
Namespace: "ns",
Name: "name",
},
},
},
ObjectNew: &v1alpha1.Application{
Spec: v1alpha1.ApplicationSpec{
Destination: v1alpha1.ApplicationDestination{
Server: "server",
Namespace: "ns",
Name: "name",
},
},
},
},
enableProgressiveSyncs: true,
}, want: false},
{name: "ApplicationDestinationDiff", args: args{e: event.UpdateEvent{
ObjectOld: &v1alpha1.Application{
Spec: v1alpha1.ApplicationSpec{
Destination: v1alpha1.ApplicationDestination{
Server: "server",
Namespace: "ns",
Name: "name",
},
},
},
ObjectNew: &v1alpha1.Application{
Spec: v1alpha1.ApplicationSpec{
Destination: v1alpha1.ApplicationDestination{
Server: "notSameServer",
Namespace: "ns",
Name: "name",
},
},
},
},
enableProgressiveSyncs: true,
}, want: true},
{name: "NotAnAppOld", args: args{e: event.UpdateEvent{
ObjectOld: &v1alpha1.AppProject{},
ObjectNew: &v1alpha1.Application{ObjectMeta: metav1.ObjectMeta{Labels: map[string]string{"bar": "foo"}}},

View File

@@ -20,6 +20,7 @@ import (
argov1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1"
"github.com/argoproj/argo-cd/v2/util/argo"
argodiff "github.com/argoproj/argo-cd/v2/util/argo/diff"
"github.com/argoproj/argo-cd/v2/util/argo/normalizers"
)
// CreateOrUpdate overrides "sigs.k8s.io/controller-runtime" function
@@ -35,7 +36,7 @@ import (
// The MutateFn is called regardless of creating or updating an object.
//
// It returns the executed operation and an error.
func CreateOrUpdate(ctx context.Context, logCtx *log.Entry, c client.Client, ignoreAppDifferences argov1alpha1.ApplicationSetIgnoreDifferences, obj *argov1alpha1.Application, f controllerutil.MutateFn) (controllerutil.OperationResult, error) {
func CreateOrUpdate(ctx context.Context, logCtx *log.Entry, c client.Client, ignoreAppDifferences argov1alpha1.ApplicationSetIgnoreDifferences, ignoreNormalizerOpts normalizers.IgnoreNormalizerOpts, obj *argov1alpha1.Application, f controllerutil.MutateFn) (controllerutil.OperationResult, error) {
key := client.ObjectKeyFromObject(obj)
if err := c.Get(ctx, key, obj); err != nil {
@@ -60,7 +61,7 @@ func CreateOrUpdate(ctx context.Context, logCtx *log.Entry, c client.Client, ign
// Apply ignoreApplicationDifferences rules to remove ignored fields from both the live and the desired state. This
// prevents those differences from appearing in the diff and therefore in the patch.
err := applyIgnoreDifferences(ignoreAppDifferences, normalizedLive, obj)
err := applyIgnoreDifferences(ignoreAppDifferences, normalizedLive, obj, ignoreNormalizerOpts)
if err != nil {
return controllerutil.OperationResultNone, fmt.Errorf("failed to apply ignore differences: %w", err)
}
@@ -134,14 +135,14 @@ func mutate(f controllerutil.MutateFn, key client.ObjectKey, obj client.Object)
}
// applyIgnoreDifferences applies the ignore differences rules to the found application. It modifies the applications in place.
func applyIgnoreDifferences(applicationSetIgnoreDifferences argov1alpha1.ApplicationSetIgnoreDifferences, found *argov1alpha1.Application, generatedApp *argov1alpha1.Application) error {
func applyIgnoreDifferences(applicationSetIgnoreDifferences argov1alpha1.ApplicationSetIgnoreDifferences, found *argov1alpha1.Application, generatedApp *argov1alpha1.Application, ignoreNormalizerOpts normalizers.IgnoreNormalizerOpts) error {
if len(applicationSetIgnoreDifferences) == 0 {
return nil
}
generatedAppCopy := generatedApp.DeepCopy()
diffConfig, err := argodiff.NewDiffConfigBuilder().
WithDiffSettings(applicationSetIgnoreDifferences.ToApplicationIgnoreDifferences(), nil, false).
WithDiffSettings(applicationSetIgnoreDifferences.ToApplicationIgnoreDifferences(), nil, false, ignoreNormalizerOpts).
WithNoCache().
Build()
if err != nil {

View File

@@ -9,6 +9,7 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1"
"github.com/argoproj/argo-cd/v2/util/argo/normalizers"
)
func Test_applyIgnoreDifferences(t *testing.T) {
@@ -222,7 +223,7 @@ spec:
generatedApp := v1alpha1.Application{TypeMeta: appMeta}
err = yaml.Unmarshal([]byte(tc.generatedApp), &generatedApp)
require.NoError(t, err, tc.generatedApp)
err = applyIgnoreDifferences(tc.ignoreDifferences, &foundApp, &generatedApp)
err = applyIgnoreDifferences(tc.ignoreDifferences, &foundApp, &generatedApp, normalizers.IgnoreNormalizerOpts{})
require.NoError(t, err)
yamlFound, err := yaml.Marshal(tc.foundApp)
require.NoError(t, err)

View File

@@ -975,6 +975,25 @@
"type": "string",
"name": "project",
"in": "query"
},
{
"type": "array",
"items": {
"type": "string",
"format": "int64"
},
"collectionFormat": "multi",
"name": "sourcePositions",
"in": "query"
},
{
"type": "array",
"items": {
"type": "string"
},
"collectionFormat": "multi",
"name": "revisions",
"in": "query"
}
],
"responses": {
@@ -4219,6 +4238,19 @@
"revision": {
"type": "string"
},
"revisions": {
"type": "array",
"items": {
"type": "string"
}
},
"sourcePositions": {
"type": "array",
"items": {
"type": "string",
"format": "int64"
}
},
"strategy": {
"$ref": "#/definitions/v1alpha1SyncStrategy"
},

View File

@@ -21,6 +21,7 @@ import (
appclientset "github.com/argoproj/argo-cd/v2/pkg/client/clientset/versioned"
"github.com/argoproj/argo-cd/v2/pkg/ratelimiter"
"github.com/argoproj/argo-cd/v2/reposerver/apiclient"
"github.com/argoproj/argo-cd/v2/util/argo/normalizers"
cacheutil "github.com/argoproj/argo-cd/v2/util/cache"
appstatecache "github.com/argoproj/argo-cd/v2/util/cache/appstate"
"github.com/argoproj/argo-cd/v2/util/cli"
@@ -72,6 +73,7 @@ func NewCommand() *cobra.Command {
shardingAlgorithm string
enableDynamicClusterDistribution bool
serverSideDiff bool
ignoreNormalizerOpts normalizers.IgnoreNormalizerOpts
)
var command = cobra.Command{
Use: cliName,
@@ -169,6 +171,7 @@ func NewCommand() *cobra.Command {
&workqueueRateLimit,
serverSideDiff,
enableDynamicClusterDistribution,
ignoreNormalizerOpts,
)
errors.CheckError(err)
cacheutil.CollectMetrics(redisClient, appController.GetMetricsServer())
@@ -229,6 +232,7 @@ func NewCommand() *cobra.Command {
command.Flags().Float64Var(&workqueueRateLimit.BackoffFactor, "wq-backoff-factor", env.ParseFloat64FromEnv("WORKQUEUE_BACKOFF_FACTOR", 1.5, 0, math.MaxFloat64), "Set Workqueue Per Item Rate Limiter Backoff Factor, default is 1.5")
command.Flags().BoolVar(&enableDynamicClusterDistribution, "dynamic-cluster-distribution-enabled", env.ParseBoolFromEnv(common.EnvEnableDynamicClusterDistribution, false), "Enables dynamic cluster distribution.")
command.Flags().BoolVar(&serverSideDiff, "server-side-diff-enabled", env.ParseBoolFromEnv(common.EnvServerSideDiff, false), "Feature flag to enable ServerSide diff. Default (\"false\")")
command.Flags().DurationVar(&ignoreNormalizerOpts.JQExecutionTimeout, "ignore-normalizer-jq-execution-timeout-seconds", env.ParseDurationFromEnv("ARGOCD_IGNORE_NORMALIZER_JQ_TIMEOUT", 0*time.Second, 0, math.MaxInt64), "Set ignore normalizer JQ execution timeout")
cacheSource = appstatecache.AddCacheFlagsToCmd(&command, cacheutil.Options{
OnClientCreated: func(client *redis.Client) {
redisClient = client

View File

@@ -48,84 +48,9 @@ func NewAdminCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command {
Run: func(c *cobra.Command, args []string) {
c.HelpFunc()(c, args)
},
Example: `# List all clusters
$ argocd admin cluster list
# Add a new cluster
$ argocd admin cluster add my-cluster --name my-cluster --in-cluster-context
# Remove a cluster
argocd admin cluster remove my-cluster
# List all projects
$ argocd admin project list
# Create a new project
$argocd admin project create my-project --src-namespace my-source-namespace --dest-namespace my-dest-namespace
# Update a project
$ argocd admin project update my-project --src-namespace my-updated-source-namespace --dest-namespace my-updated-dest-namespace
# Delete a project
$ argocd admin project delete my-project
# List all settings
$ argocd admin settings list
# Get the current settings
$ argocd admin settings get
# Update settings
$ argocd admin settings update --repository.resync --value 15
# List all applications
$ argocd admin app list
# Get application details
$ argocd admin app get my-app
# Sync an application
$ argocd admin app sync my-app
# Pause an application
$ argocd admin app pause my-app
# Resume an application
$ argocd admin app resume my-app
# List all repositories
$ argocd admin repo list
# Add a repository
$ argocd admin repo add https://github.com/argoproj/my-repo.git
# Remove a repository
$ argocd admin repo remove https://github.com/argoproj/my-repo.git
# Import an application from a YAML file
$ argocd admin app import -f my-app.yaml
# Export an application to a YAML file
$ argocd admin app export my-app -o my-exported-app.yaml
# Access the Argo CD web UI
Example: `# Access the Argo CD web UI
$ argocd admin dashboard
# List notifications
$ argocd admin notification list
# Get notification details
$ argocd admin notification get my-notification
# Create a new notification
$ argocd admin notification create my-notification -f notification-config.yaml
# Update a notification
$ argocd admin notification update my-notification -f updated-notification-config.yaml
# Delete a notification
$ argocd admin notification delete my-notification
# Reset the initial admin password
$ argocd admin initial-password reset
`,

View File

@@ -31,6 +31,7 @@ import (
appinformers "github.com/argoproj/argo-cd/v2/pkg/client/informers/externalversions"
reposerverclient "github.com/argoproj/argo-cd/v2/reposerver/apiclient"
"github.com/argoproj/argo-cd/v2/util/argo"
"github.com/argoproj/argo-cd/v2/util/argo/normalizers"
cacheutil "github.com/argoproj/argo-cd/v2/util/cache"
appstatecache "github.com/argoproj/argo-cd/v2/util/cache/appstate"
"github.com/argoproj/argo-cd/v2/util/cli"
@@ -239,12 +240,13 @@ func diffReconcileResults(res1 reconcileResults, res2 reconcileResults) error {
func NewReconcileCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command {
var (
clientConfig clientcmd.ClientConfig
selector string
repoServerAddress string
outputFormat string
refresh bool
serverSideDiff bool
clientConfig clientcmd.ClientConfig
selector string
repoServerAddress string
outputFormat string
refresh bool
serverSideDiff bool
ignoreNormalizerOpts normalizers.IgnoreNormalizerOpts
)
var command = &cobra.Command{
@@ -290,7 +292,7 @@ func NewReconcileCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command
repoServerAddress = fmt.Sprintf("localhost:%d", repoServerPort)
}
repoServerClient := reposerverclient.NewRepoServerClientset(repoServerAddress, 60, reposerverclient.TLSConfiguration{DisableTLS: false, StrictValidation: false})
result, err = reconcileApplications(ctx, kubeClientset, appClientset, namespace, repoServerClient, selector, newLiveStateCache, serverSideDiff)
result, err = reconcileApplications(ctx, kubeClientset, appClientset, namespace, repoServerClient, selector, newLiveStateCache, serverSideDiff, ignoreNormalizerOpts)
errors.CheckError(err)
} else {
appClientset := appclientset.NewForConfigOrDie(cfg)
@@ -306,7 +308,7 @@ func NewReconcileCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command
command.Flags().StringVar(&outputFormat, "o", "yaml", "Output format (yaml|json)")
command.Flags().BoolVar(&refresh, "refresh", false, "If set to true then recalculates apps reconciliation")
command.Flags().BoolVar(&serverSideDiff, "server-side-diff", false, "If set to \"true\" will use server-side diff while comparing resources. Default (\"false\")")
command.Flags().DurationVar(&ignoreNormalizerOpts.JQExecutionTimeout, "ignore-normalizer-jq-execution-timeout", normalizers.DefaultJQExecutionTimeout, "Set ignore normalizer JQ execution timeout")
return command
}
@@ -356,6 +358,7 @@ func reconcileApplications(
selector string,
createLiveStateCache func(argoDB db.ArgoDB, appInformer kubecache.SharedIndexInformer, settingsMgr *settings.SettingsManager, server *metrics.MetricsServer) cache.LiveStateCache,
serverSideDiff bool,
ignoreNormalizerOpts normalizers.IgnoreNormalizerOpts,
) ([]appReconcileResult, error) {
settingsMgr := settings.NewSettingsManager(ctx, kubeClientset, namespace)
argoDB := db.NewDB(namespace, settingsMgr, kubeClientset)
@@ -396,7 +399,7 @@ func reconcileApplications(
)
appStateManager := controller.NewAppStateManager(
argoDB, appClientset, repoServerClient, namespace, kubeutil.NewKubectl(), settingsMgr, stateCache, projInformer, server, cache, time.Second, argo.NewResourceTracking(), false, 0, serverSideDiff)
argoDB, appClientset, repoServerClient, namespace, kubeutil.NewKubectl(), settingsMgr, stateCache, projInformer, server, cache, time.Second, argo.NewResourceTracking(), false, 0, serverSideDiff, ignoreNormalizerOpts)
appsList, err := appClientset.ArgoprojV1alpha1().Applications(namespace).List(ctx, v1.ListOptions{LabelSelector: selector})
if err != nil {

View File

@@ -23,6 +23,7 @@ import (
argocdclient "github.com/argoproj/argo-cd/v2/reposerver/apiclient"
"github.com/argoproj/argo-cd/v2/reposerver/apiclient/mocks"
"github.com/argoproj/argo-cd/v2/test"
"github.com/argoproj/argo-cd/v2/util/argo/normalizers"
"github.com/argoproj/argo-cd/v2/util/db"
"github.com/argoproj/argo-cd/v2/util/settings"
)
@@ -114,6 +115,7 @@ func TestGetReconcileResults_Refresh(t *testing.T) {
return &liveStateCache
},
false,
normalizers.IgnoreNormalizerOpts{},
)
if !assert.NoError(t, err) {

View File

@@ -428,7 +428,7 @@ argocd admin settings resource-overrides ignore-differences ./deploy.yaml --argo
// configurations. This requires access to live resources which is not the
// purpose of this command. This will just apply jsonPointers and
// jqPathExpressions configurations.
normalizer, err := normalizers.NewIgnoreNormalizer(nil, overrides)
normalizer, err := normalizers.NewIgnoreNormalizer(nil, overrides, normalizers.IgnoreNormalizerOpts{})
errors.CheckError(err)
normalizedRes := res.DeepCopy()
@@ -453,6 +453,9 @@ argocd admin settings resource-overrides ignore-differences ./deploy.yaml --argo
}
func NewResourceIgnoreResourceUpdatesCommand(cmdCtx commandContext) *cobra.Command {
var (
ignoreNormalizerOpts normalizers.IgnoreNormalizerOpts
)
var command = &cobra.Command{
Use: "ignore-resource-updates RESOURCE_YAML_PATH",
Short: "Renders fields excluded from resource updates",
@@ -474,7 +477,7 @@ argocd admin settings resource-overrides ignore-resource-updates ./deploy.yaml -
return
}
normalizer, err := normalizers.NewIgnoreNormalizer(nil, overrides)
normalizer, err := normalizers.NewIgnoreNormalizer(nil, overrides, ignoreNormalizerOpts)
errors.CheckError(err)
normalizedRes := res.DeepCopy()
@@ -495,6 +498,7 @@ argocd admin settings resource-overrides ignore-resource-updates ./deploy.yaml -
})
},
}
command.Flags().DurationVar(&ignoreNormalizerOpts.JQExecutionTimeout, "ignore-normalizer-jq-execution-timeout", normalizers.DefaultJQExecutionTimeout, "Set ignore normalizer JQ execution timeout")
return command
}

View File

@@ -45,6 +45,7 @@ import (
"github.com/argoproj/argo-cd/v2/reposerver/repository"
"github.com/argoproj/argo-cd/v2/util/argo"
argodiff "github.com/argoproj/argo-cd/v2/util/argo/diff"
"github.com/argoproj/argo-cd/v2/util/argo/normalizers"
"github.com/argoproj/argo-cd/v2/util/cli"
"github.com/argoproj/argo-cd/v2/util/errors"
"github.com/argoproj/argo-cd/v2/util/git"
@@ -730,9 +731,9 @@ func getServer(app *argoappv1.Application) string {
// NewApplicationSetCommand returns a new instance of an `argocd app set` command
func NewApplicationSetCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command {
var (
appOpts cmdutil.AppOptions
appNamespace string
sourceIndex int
appOpts cmdutil.AppOptions
appNamespace string
sourcePosition int
)
var command = &cobra.Command{
Use: "set APPNAME",
@@ -750,8 +751,8 @@ func NewApplicationSetCommand(clientOpts *argocdclient.ClientOptions) *cobra.Com
# Set and override application parameters with a parameter file
argocd app set my-app --parameter-file path/to/parameter-file.yaml
# Set and override application parameters for a source at index 1 under spec.sources of app my-app. source-index starts at 1.
argocd app set my-app --source-index 1 --repo https://github.com/argoproj/argocd-example-apps.git
# Set and override application parameters for a source at position 1 under spec.sources of app my-app. source-position starts at 1.
argocd app set my-app --source-position 1 --repo https://github.com/argoproj/argocd-example-apps.git
# Set application parameters and specify the namespace
argocd app set my-app --parameter key1=value1 --parameter key2=value2 --namespace my-namespace
@@ -772,24 +773,24 @@ func NewApplicationSetCommand(clientOpts *argocdclient.ClientOptions) *cobra.Com
errors.CheckError(err)
if app.Spec.HasMultipleSources() {
if sourceIndex <= 0 {
errors.CheckError(fmt.Errorf("Source index should be specified and greater than 0 for applications with multiple sources"))
if sourcePosition <= 0 {
errors.CheckError(fmt.Errorf("Source position should be specified and must be greater than 0 for applications with multiple sources"))
}
if len(app.Spec.GetSources()) < sourceIndex {
errors.CheckError(fmt.Errorf("Source index should be less than the number of sources in the application"))
if len(app.Spec.GetSources()) < sourcePosition {
errors.CheckError(fmt.Errorf("Source position should be less than the number of sources in the application"))
}
}
// sourceIndex startes with 1, thus, it needs to be decreased by 1 to find the correct index in the list of sources
sourceIndex = sourceIndex - 1
visited := cmdutil.SetAppSpecOptions(c.Flags(), &app.Spec, &appOpts, sourceIndex)
// sourcePosition startes with 1, thus, it needs to be decreased by 1 to find the correct index in the list of sources
sourcePosition = sourcePosition - 1
visited := cmdutil.SetAppSpecOptions(c.Flags(), &app.Spec, &appOpts, sourcePosition)
if visited == 0 {
log.Error("Please set at least one option to update")
c.HelpFunc()(c, args)
os.Exit(1)
}
setParameterOverrides(app, appOpts.Parameters, sourceIndex)
setParameterOverrides(app, appOpts.Parameters, sourcePosition)
_, err = appIf.UpdateSpec(ctx, &application.ApplicationUpdateSpecRequest{
Name: &app.Name,
Spec: &app.Spec,
@@ -799,7 +800,7 @@ func NewApplicationSetCommand(clientOpts *argocdclient.ClientOptions) *cobra.Com
errors.CheckError(err)
},
}
command.Flags().IntVar(&sourceIndex, "source-index", -1, "Index of the source from the list of sources of the app. Index starts at 1.")
command.Flags().IntVar(&sourcePosition, "source-position", -1, "Position of the source from the list of sources of the app. Counting starts at 1.")
cmdutil.AddAppFlags(command, &appOpts)
command.Flags().StringVarP(&appNamespace, "app-namespace", "N", "", "Set application parameters in namespace")
return command
@@ -836,7 +837,7 @@ func (o *unsetOpts) KustomizeIsZero() bool {
// NewApplicationUnsetCommand returns a new instance of an `argocd app unset` command
func NewApplicationUnsetCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command {
var (
sourceIndex int
sourcePosition int
)
appOpts := cmdutil.AppOptions{}
opts := unsetOpts{}
@@ -850,8 +851,8 @@ func NewApplicationUnsetCommand(clientOpts *argocdclient.ClientOptions) *cobra.C
# Unset kustomize override suffix
argocd app unset my-app --namesuffix
# Unset kustomize override suffix for source at index 1 under spec.sources of app my-app. source-index starts at 1.
argocd app unset my-app --source-index 1 --namesuffix
# Unset kustomize override suffix for source at position 1 under spec.sources of app my-app. source-position starts at 1.
argocd app unset my-app --source-position 1 --namesuffix
# Unset parameter override
argocd app unset my-app -p COMPONENT=PARAM`,
@@ -871,15 +872,15 @@ func NewApplicationUnsetCommand(clientOpts *argocdclient.ClientOptions) *cobra.C
errors.CheckError(err)
if app.Spec.HasMultipleSources() {
if sourceIndex <= 0 {
errors.CheckError(fmt.Errorf("Source index should be specified and greater than 0 for applications with multiple sources"))
if sourcePosition <= 0 {
errors.CheckError(fmt.Errorf("Source position should be specified and must be greater than 0 for applications with multiple sources"))
}
if len(app.Spec.GetSources()) < sourceIndex {
errors.CheckError(fmt.Errorf("Source index should be less than the number of sources in the application"))
if len(app.Spec.GetSources()) < sourcePosition {
errors.CheckError(fmt.Errorf("Source position should be less than the number of sources in the application"))
}
}
source := app.Spec.GetSourcePtr(sourceIndex)
source := app.Spec.GetSourcePtrByPosition(sourcePosition)
updated, nothingToUnset := unset(source, opts)
if nothingToUnset {
@@ -890,7 +891,7 @@ func NewApplicationUnsetCommand(clientOpts *argocdclient.ClientOptions) *cobra.C
return
}
cmdutil.SetAppSpecOptions(c.Flags(), &app.Spec, &appOpts, sourceIndex)
cmdutil.SetAppSpecOptions(c.Flags(), &app.Spec, &appOpts, sourcePosition)
_, err = appIf.UpdateSpec(ctx, &application.ApplicationUpdateSpecRequest{
Name: &app.Name,
Spec: &app.Spec,
@@ -914,7 +915,7 @@ func NewApplicationUnsetCommand(clientOpts *argocdclient.ClientOptions) *cobra.C
command.Flags().StringArrayVar(&opts.pluginEnvs, "plugin-env", []string{}, "Unset plugin env variables (e.g --plugin-env name)")
command.Flags().BoolVar(&opts.passCredentials, "pass-credentials", false, "Unset passCredentials")
command.Flags().BoolVar(&opts.ref, "ref", false, "Unset ref on the source")
command.Flags().IntVar(&sourceIndex, "source-index", -1, "Index of the source from the list of sources of the app. Index starts at 1.")
command.Flags().IntVar(&sourcePosition, "source-position", -1, "Position of the source from the list of sources of the app. Counting starts at 1.")
return command
}
@@ -1116,17 +1117,18 @@ type objKeyLiveTarget struct {
// NewApplicationDiffCommand returns a new instance of an `argocd app diff` command
func NewApplicationDiffCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command {
var (
refresh bool
hardRefresh bool
exitCode bool
local string
revision string
localRepoRoot string
serverSideGenerate bool
localIncludes []string
appNamespace string
revisions []string
sourceIndexes []int64
refresh bool
hardRefresh bool
exitCode bool
local string
revision string
localRepoRoot string
serverSideGenerate bool
localIncludes []string
appNamespace string
revisions []string
sourcePositions []int64
ignoreNormalizerOpts normalizers.IgnoreNormalizerOpts
)
shortDesc := "Perform a diff against the target and live state."
var command = &cobra.Command{
@@ -1141,8 +1143,8 @@ func NewApplicationDiffCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co
os.Exit(2)
}
if len(revisions) != len(sourceIndexes) {
errors.CheckError(fmt.Errorf("While using revisions and source-indexes, length of values for both flags should be same."))
if len(revisions) != len(sourcePositions) {
errors.CheckError(fmt.Errorf("While using revisions and source-positions, length of values for both flags should be same."))
}
clientset := headless.NewClientOrDie(clientOpts, c)
@@ -1163,26 +1165,26 @@ func NewApplicationDiffCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co
argoSettings, err := settingsIf.Get(ctx, &settings.SettingsQuery{})
errors.CheckError(err)
diffOption := &DifferenceOption{}
if app.Spec.HasMultipleSources() && len(revisions) > 0 && len(sourceIndexes) > 0 {
revisionSourceMappings := make(map[int64]string, 0)
for i, index := range sourceIndexes {
if index <= 0 {
errors.CheckError(fmt.Errorf("source-index cannot be less than or equal to 0. Index starts at 1."))
if app.Spec.HasMultipleSources() && len(revisions) > 0 && len(sourcePositions) > 0 {
numOfSources := int64(len(app.Spec.GetSources()))
for _, pos := range sourcePositions {
if pos <= 0 || pos > numOfSources {
log.Fatal("source-position cannot be less than 1 or more than number of sources in the app. Counting starts at 1.")
}
revisionSourceMappings[index] = revisions[i]
}
q := application.ApplicationManifestQuery{
Name: &appName,
AppNamespace: &appNs,
RevisionSourceMappings: revisionSourceMappings,
Name: &appName,
AppNamespace: &appNs,
Revisions: revisions,
SourcePositions: sourcePositions,
}
res, err := appIf.GetManifests(ctx, &q)
errors.CheckError(err)
diffOption.res = res
diffOption.revisionSourceMappings = &revisionSourceMappings
diffOption.revisions = revisions
diffOption.sourcePositions = sourcePositions
} else if revision != "" {
q := application.ApplicationManifestQuery{
Name: &appName,
@@ -1218,7 +1220,7 @@ func NewApplicationDiffCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co
}
}
proj := getProject(c, clientOpts, ctx, app.Spec.Project)
foundDiffs := findandPrintDiff(ctx, app, proj.Project, resources, argoSettings, diffOption)
foundDiffs := findandPrintDiff(ctx, app, proj.Project, resources, argoSettings, diffOption, ignoreNormalizerOpts)
if foundDiffs && exitCode {
os.Exit(1)
}
@@ -1233,24 +1235,26 @@ func NewApplicationDiffCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co
command.Flags().BoolVar(&serverSideGenerate, "server-side-generate", false, "Used with --local, this will send your manifests to the server for diffing")
command.Flags().StringArrayVar(&localIncludes, "local-include", []string{"*.yaml", "*.yml", "*.json"}, "Used with --server-side-generate, specify patterns of filenames to send. Matching is based on filename and not path.")
command.Flags().StringVarP(&appNamespace, "app-namespace", "N", "", "Only render the difference in namespace")
command.Flags().StringArrayVar(&revisions, "revisions", []string{}, "Show manifests at specific revisions for the index of sources in source-indexes")
command.Flags().Int64SliceVar(&sourceIndexes, "source-indexes", []int64{}, "List of source indexes. Default is empty array. Indexes start at 1.")
command.Flags().StringArrayVar(&revisions, "revisions", []string{}, "Show manifests at specific revisions for source position in source-positions")
command.Flags().Int64SliceVar(&sourcePositions, "source-positions", []int64{}, "List of source positions. Default is empty array. Counting start at 1.")
command.Flags().DurationVar(&ignoreNormalizerOpts.JQExecutionTimeout, "ignore-normalizer-jq-execution-timeout", normalizers.DefaultJQExecutionTimeout, "Set ignore normalizer JQ execution timeout")
return command
}
// DifferenceOption struct to store diff options
type DifferenceOption struct {
local string
localRepoRoot string
revision string
cluster *argoappv1.Cluster
res *repoapiclient.ManifestResponse
serversideRes *repoapiclient.ManifestResponse
revisionSourceMappings *map[int64]string
local string
localRepoRoot string
revision string
cluster *argoappv1.Cluster
res *repoapiclient.ManifestResponse
serversideRes *repoapiclient.ManifestResponse
revisions []string
sourcePositions []int64
}
// findandPrintDiff ... Prints difference between application current state and state stored in git or locally, returns boolean as true if difference is found else returns false
func findandPrintDiff(ctx context.Context, app *argoappv1.Application, proj *argoappv1.AppProject, resources *application.ManagedResourcesResponse, argoSettings *settings.Settings, diffOptions *DifferenceOption) bool {
func findandPrintDiff(ctx context.Context, app *argoappv1.Application, proj *argoappv1.AppProject, resources *application.ManagedResourcesResponse, argoSettings *settings.Settings, diffOptions *DifferenceOption, ignoreNormalizerOpts normalizers.IgnoreNormalizerOpts) bool {
var foundDiffs bool
liveObjs, err := cmdutil.LiveObjects(resources.Items)
errors.CheckError(err)
@@ -1258,7 +1262,7 @@ func findandPrintDiff(ctx context.Context, app *argoappv1.Application, proj *arg
if diffOptions.local != "" {
localObjs := groupObjsByKey(getLocalObjects(ctx, app, proj, diffOptions.local, diffOptions.localRepoRoot, argoSettings.AppLabelKey, diffOptions.cluster.Info.ServerVersion, diffOptions.cluster.Info.APIVersions, argoSettings.KustomizeOptions, argoSettings.TrackingMethod), liveObjs, app.Spec.Destination.Namespace)
items = groupObjsForDiff(resources, localObjs, items, argoSettings, app.InstanceName(argoSettings.ControllerNamespace), app.Spec.Destination.Namespace)
} else if diffOptions.revision != "" || (diffOptions.revisionSourceMappings != nil) {
} else if diffOptions.revision != "" || (diffOptions.revisions != nil && len(diffOptions.revisions) > 0) {
var unstructureds []*unstructured.Unstructured
for _, mfst := range diffOptions.res.Manifests {
obj, err := argoappv1.UnmarshalToUnstructured(mfst)
@@ -1305,7 +1309,7 @@ func findandPrintDiff(ctx context.Context, app *argoappv1.Application, proj *arg
// compareOptions in the protobuf
ignoreAggregatedRoles := false
diffConfig, err := argodiff.NewDiffConfigBuilder().
WithDiffSettings(app.Spec.IgnoreDifferences, overrides, ignoreAggregatedRoles).
WithDiffSettings(app.Spec.IgnoreDifferences, overrides, ignoreAggregatedRoles, ignoreNormalizerOpts).
WithTracking(argoSettings.AppLabelKey, argoSettings.TrackingMethod).
WithNoCache().
Build()
@@ -1803,6 +1807,8 @@ func printTreeViewDetailed(nodeMapping map[string]argoappv1.ResourceNode, parent
func NewApplicationSyncCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command {
var (
revision string
revisions []string
sourcePositions []int64
resources []string
labels []string
selector string
@@ -1827,6 +1833,7 @@ func NewApplicationSyncCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co
projects []string
output string
appNamespace string
ignoreNormalizerOpts normalizers.IgnoreNormalizerOpts
)
var command = &cobra.Command{
Use: "sync [APPNAME... | -l selector | --project project-name]",
@@ -1844,6 +1851,9 @@ func NewApplicationSyncCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co
argocd app sync -l '!app.kubernetes.io/instance'
argocd app sync -l 'app.kubernetes.io/instance notin (my-app,other-app)'
# Sync a multi-source application for specific revision of specific sources
argocd app manifests my-app --revisions 0.0.1 --source-positions 1 --revisions 0.0.2 --source-positions 2
# Sync a specific resource
# Resource should be formatted as GROUP:KIND:NAME. If no GROUP is specified then :KIND:NAME
argocd app sync my-app --resource :Service:my-service
@@ -1862,6 +1872,21 @@ func NewApplicationSyncCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co
if len(args) > 1 && selector != "" {
log.Fatal("Cannot use selector option when application name(s) passed as argument(s)")
}
if len(args) != 1 && (len(revisions) > 0 || len(sourcePositions) > 0) {
log.Fatal("Cannot use --revisions and --source-positions options when 0 or more than 1 application names are passed as argument(s)")
}
if len(revisions) != len(sourcePositions) {
log.Fatal("While using --revisions and --source-positions, length of values for both flags should be same.")
}
for _, pos := range sourcePositions {
if pos <= 0 {
log.Fatal("source-position cannot be less than or equal to 0, Counting starts at 1")
}
}
acdClient := headless.NewClientOrDie(clientOpts, c)
conn, appIf := acdClient.NewApplicationClientOrDie()
defer argoio.Close(conn)
@@ -1903,9 +1928,11 @@ func NewApplicationSyncCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co
if len(selectedLabels) > 0 {
q := application.ApplicationManifestQuery{
Name: &appName,
AppNamespace: &appNs,
Revision: &revision,
Name: &appName,
AppNamespace: &appNs,
Revision: &revision,
Revisions: revisions,
SourcePositions: sourcePositions,
}
res, err := appIf.GetManifests(ctx, &q)
@@ -1948,7 +1975,7 @@ func NewApplicationSyncCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co
if app.Spec.HasMultipleSources() {
if revision != "" {
log.Fatal("argocd cli does not work on multi-source app with --revision flag")
log.Fatal("argocd cli does not work on multi-source app with --revision flag. Use --revisions and --source-position instead.")
return
}
@@ -2013,15 +2040,17 @@ func NewApplicationSyncCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co
}
syncReq := application.ApplicationSyncRequest{
Name: &appName,
AppNamespace: &appNs,
DryRun: &dryRun,
Revision: &revision,
Resources: filteredResources,
Prune: &prune,
Manifests: localObjsStrings,
Infos: getInfos(infos),
SyncOptions: syncOptionsFactory(),
Name: &appName,
AppNamespace: &appNs,
DryRun: &dryRun,
Revision: &revision,
Resources: filteredResources,
Prune: &prune,
Manifests: localObjsStrings,
Infos: getInfos(infos),
SyncOptions: syncOptionsFactory(),
Revisions: revisions,
SourcePositions: sourcePositions,
}
switch strategy {
@@ -2058,7 +2087,7 @@ func NewApplicationSyncCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co
fmt.Printf("====== Previewing differences between live and desired state of application %s ======\n", appQualifiedName)
proj := getProject(c, clientOpts, ctx, app.Spec.Project)
foundDiffs = findandPrintDiff(ctx, app, proj.Project, resources, argoSettings, diffOption)
foundDiffs = findandPrintDiff(ctx, app, proj.Project, resources, argoSettings, diffOption, ignoreNormalizerOpts)
if foundDiffs {
if !diffChangesConfirm {
yesno := cli.AskToProceed(fmt.Sprintf("Please review changes to application %s shown above. Do you want to continue the sync process? (y/n): ", appQualifiedName))
@@ -2117,6 +2146,9 @@ func NewApplicationSyncCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co
command.Flags().StringArrayVar(&projects, "project", []string{}, "Sync apps that belong to the specified projects. This option may be specified repeatedly.")
command.Flags().StringVarP(&output, "output", "o", "wide", "Output format. One of: json|yaml|wide|tree|tree=detailed")
command.Flags().StringVarP(&appNamespace, "app-namespace", "N", "", "Only sync an application in namespace")
command.Flags().DurationVar(&ignoreNormalizerOpts.JQExecutionTimeout, "ignore-normalizer-jq-execution-timeout", normalizers.DefaultJQExecutionTimeout, "Set ignore normalizer JQ execution timeout")
command.Flags().StringArrayVar(&revisions, "revisions", []string{}, "Show manifests at specific revisions for source position in source-positions")
command.Flags().Int64SliceVar(&sourcePositions, "source-positions", []int64{}, "List of source positions. Default is empty array. Counting start at 1.")
return command
}
@@ -2495,11 +2527,11 @@ func waitOnApplicationStatus(ctx context.Context, acdClient argocdclient.Client,
// setParameterOverrides updates an existing or appends a new parameter override in the application
// the app is assumed to be a helm app and is expected to be in the form:
// param=value
func setParameterOverrides(app *argoappv1.Application, parameters []string, index int) {
func setParameterOverrides(app *argoappv1.Application, parameters []string, sourcePosition int) {
if len(parameters) == 0 {
return
}
source := app.Spec.GetSourcePtr(index)
source := app.Spec.GetSourcePtrByPosition(sourcePosition)
var sourceType argoappv1.ApplicationSourceType
if st, _ := source.ExplicitType(); st != nil {
sourceType = *st
@@ -2736,12 +2768,12 @@ func printOperationResult(opState *argoappv1.OperationState) {
// NewApplicationManifestsCommand returns a new instance of an `argocd app manifests` command
func NewApplicationManifestsCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command {
var (
source string
revision string
revisions []string
sourceIndexes []int64
local string
localRepoRoot string
source string
revision string
revisions []string
sourcePositions []int64
local string
localRepoRoot string
)
var command = &cobra.Command{
Use: "manifests APPNAME",
@@ -2754,7 +2786,7 @@ func NewApplicationManifestsCommand(clientOpts *argocdclient.ClientOptions) *cob
argocd app manifests my-app --revision 0.0.1
# Get manifests for a multi-source application at specific revisions for specific sources
argocd app manifests my-app --revisions 0.0.1 --source-indexes 1 --revisions 0.0.2 --source-indexes 2
argocd app manifests my-app --revisions 0.0.1 --source-positions 1 --revisions 0.0.2 --source-positions 2
`),
Run: func(c *cobra.Command, args []string) {
ctx := c.Context()
@@ -2764,8 +2796,14 @@ func NewApplicationManifestsCommand(clientOpts *argocdclient.ClientOptions) *cob
os.Exit(1)
}
if len(revisions) != len(sourceIndexes) {
errors.CheckError(fmt.Errorf("While using revisions and source-indexes, length of values for both flags should be same."))
if len(revisions) != len(sourcePositions) {
errors.CheckError(fmt.Errorf("While using revisions and source-positions, length of values for both flags should be same."))
}
for _, pos := range sourcePositions {
if pos <= 0 {
log.Fatal("source-position cannot be less than or equal to 0, Counting starts at 1")
}
}
appName, appNs := argo.ParseFromQualifiedName(args[0], "")
@@ -2798,21 +2836,14 @@ func NewApplicationManifestsCommand(clientOpts *argocdclient.ClientOptions) *cob
proj := getProject(c, clientOpts, ctx, app.Spec.Project)
unstructureds = getLocalObjects(context.Background(), app, proj.Project, local, localRepoRoot, argoSettings.AppLabelKey, cluster.ServerVersion, cluster.Info.APIVersions, argoSettings.KustomizeOptions, argoSettings.TrackingMethod)
} else if len(revisions) > 0 && len(sourceIndexes) > 0 {
revisionSourceMappings := make(map[int64]string, 0)
for i, index := range sourceIndexes {
if index <= 0 {
errors.CheckError(fmt.Errorf("source-index cannot be less than or equal to 0, Index starts at 1"))
}
revisionSourceMappings[index] = revisions[i]
}
} else if len(revisions) > 0 && len(sourcePositions) > 0 {
q := application.ApplicationManifestQuery{
Name: &appName,
AppNamespace: &appNs,
Revision: pointer.String(revision),
RevisionSourceMappings: revisionSourceMappings,
Name: &appName,
AppNamespace: &appNs,
Revision: pointer.String(revision),
Revisions: revisions,
SourcePositions: sourcePositions,
}
res, err := appIf.GetManifests(ctx, &q)
errors.CheckError(err)
@@ -2859,8 +2890,8 @@ func NewApplicationManifestsCommand(clientOpts *argocdclient.ClientOptions) *cob
}
command.Flags().StringVar(&source, "source", "git", "Source of manifests. One of: live|git")
command.Flags().StringVar(&revision, "revision", "", "Show manifests at a specific revision")
command.Flags().StringArrayVar(&revisions, "revisions", []string{}, "Show manifests at specific revisions for the index of sources in source-indexes")
command.Flags().Int64SliceVar(&sourceIndexes, "source-indexes", []int64{}, "List of source indexes. Default is empty array. Indexes start at 1.")
command.Flags().StringArrayVar(&revisions, "revisions", []string{}, "Show manifests at specific revisions for the source at position in source-positions")
command.Flags().Int64SliceVar(&sourcePositions, "source-positions", []int64{}, "List of source positions. Default is empty array. Counting start at 1.")
command.Flags().StringVar(&local, "local", "", "If set, show locally-generated manifests. Value is the absolute path to app manifests within the manifest repo. Example: '/home/username/apps/env/app-1'.")
command.Flags().StringVar(&localRepoRoot, "local-repo-root", ".", "Path to the local repository root. Used together with --local allows setting the repository root. Example: '/home/username/apps'.")
return command
@@ -3040,11 +3071,11 @@ func NewApplicationAddSourceCommand(clientOpts *argocdclient.ClientOptions) *cob
if len(app.Spec.Sources) > 0 {
appSource, _ := cmdutil.ConstructSource(&argoappv1.ApplicationSource{}, appOpts, c.Flags())
// sourceIndex is the index at which new source will be appended to spec.Sources
sourceIndex := len(app.Spec.GetSources())
// sourcePosition is the index at which new source will be appended to spec.Sources
sourcePosition := len(app.Spec.GetSources())
app.Spec.Sources = append(app.Spec.Sources, *appSource)
setParameterOverrides(app, appOpts.Parameters, sourceIndex)
setParameterOverrides(app, appOpts.Parameters, sourcePosition)
_, err = appIf.UpdateSpec(ctx, &application.ApplicationUpdateSpecRequest{
Name: &app.Name,
@@ -3068,14 +3099,14 @@ func NewApplicationAddSourceCommand(clientOpts *argocdclient.ClientOptions) *cob
// NewApplicationRemoveSourceCommand returns a new instance of an `argocd app remove-source` command
func NewApplicationRemoveSourceCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command {
var (
sourceIndex int
appNamespace string
sourcePosition int
appNamespace string
)
command := &cobra.Command{
Use: "remove-source APPNAME",
Short: "Remove a source from multiple sources application. Index starts with 1. Default value is -1.",
Example: ` # Remove the source at index 1 from application's sources. Index starts at 1.
argocd app remove-source myapplication --source-index 1`,
Short: "Remove a source from multiple sources application. Counting starts with 1. Default value is -1.",
Example: ` # Remove the source at position 1 from application's sources. Counting starts at 1.
argocd app remove-source myapplication --source-position 1`,
Run: func(c *cobra.Command, args []string) {
ctx := c.Context()
@@ -3084,8 +3115,8 @@ func NewApplicationRemoveSourceCommand(clientOpts *argocdclient.ClientOptions) *
os.Exit(1)
}
if sourceIndex <= 0 {
errors.CheckError(fmt.Errorf("Index value of source must be greater than 0"))
if sourcePosition <= 0 {
errors.CheckError(fmt.Errorf("Value of source-position must be greater than 0"))
}
argocdClient := headless.NewClientOrDie(clientOpts, c)
@@ -3109,11 +3140,11 @@ func NewApplicationRemoveSourceCommand(clientOpts *argocdclient.ClientOptions) *
errors.CheckError(fmt.Errorf("Cannot remove the only source remaining in the app"))
}
if len(app.Spec.GetSources()) < sourceIndex {
errors.CheckError(fmt.Errorf("Application does not have source at %d\n", sourceIndex))
if len(app.Spec.GetSources()) < sourcePosition {
errors.CheckError(fmt.Errorf("Application does not have source at %d\n", sourcePosition))
}
app.Spec.Sources = append(app.Spec.Sources[:sourceIndex-1], app.Spec.Sources[sourceIndex:]...)
app.Spec.Sources = append(app.Spec.Sources[:sourcePosition-1], app.Spec.Sources[sourcePosition:]...)
_, err = appIf.UpdateSpec(ctx, &application.ApplicationUpdateSpecRequest{
Name: &app.Name,
@@ -3126,6 +3157,6 @@ func NewApplicationRemoveSourceCommand(clientOpts *argocdclient.ClientOptions) *
},
}
command.Flags().StringVarP(&appNamespace, "app-namespace", "N", "", "Namespace of the target application where the source will be appended")
command.Flags().IntVar(&sourceIndex, "source-index", -1, "Index of the source from the list of sources of the app. Index starts from 1.")
command.Flags().IntVar(&sourcePosition, "source-position", -1, "Position of the source from the list of sources of the app. Counting starts at 1.")
return command
}

View File

@@ -139,21 +139,21 @@ func AddAppFlags(command *cobra.Command, opts *AppOptions) {
command.Flags().StringVar(&opts.ref, "ref", "", "Ref is reference to another source within sources field")
}
func SetAppSpecOptions(flags *pflag.FlagSet, spec *argoappv1.ApplicationSpec, appOpts *AppOptions, index int) int {
func SetAppSpecOptions(flags *pflag.FlagSet, spec *argoappv1.ApplicationSpec, appOpts *AppOptions, sourcePosition int) int {
visited := 0
if flags == nil {
return visited
}
source := spec.GetSourcePtr(index)
source := spec.GetSourcePtrByPosition(sourcePosition)
if source == nil {
source = &argoappv1.ApplicationSource{}
}
source, visited = ConstructSource(source, *appOpts, flags)
if spec.HasMultipleSources() {
if index == 0 {
spec.Sources[index] = *source
} else if index > 0 {
spec.Sources[index-1] = *source
if sourcePosition == 0 {
spec.Sources[sourcePosition] = *source
} else if sourcePosition > 0 {
spec.Sources[sourcePosition-1] = *source
} else {
spec.Sources = append(spec.Sources, *source)
}
@@ -428,7 +428,7 @@ func SetParameterOverrides(app *argoappv1.Application, parameters []string, inde
if len(parameters) == 0 {
return
}
source := app.Spec.GetSourcePtr(index)
source := app.Spec.GetSourcePtrByIndex(index)
var sourceType argoappv1.ApplicationSourceType
if st, _ := source.ExplicitType(); st != nil {
sourceType = *st

View File

@@ -174,12 +174,12 @@ func (f *appOptionsFixture) SetFlag(key, value string) error {
return err
}
func (f *appOptionsFixture) SetFlagWithSourceIndex(key, value string, index int) error {
func (f *appOptionsFixture) SetFlagWithSourcePosition(key, value string, sourcePosition int) error {
err := f.command.Flags().Set(key, value)
if err != nil {
return err
}
_ = SetAppSpecOptions(f.command.Flags(), f.spec, f.options, index)
_ = SetAppSpecOptions(f.command.Flags(), f.spec, f.options, sourcePosition)
return err
}
@@ -251,34 +251,34 @@ func newMultiSourceAppOptionsFixture() *appOptionsFixture {
func Test_setAppSpecOptionsMultiSourceApp(t *testing.T) {
f := newMultiSourceAppOptionsFixture()
index := 0
index1 := 1
index2 := 2
sourcePosition := 0
sourcePosition1 := 1
sourcePosition2 := 2
t.Run("SyncPolicy", func(t *testing.T) {
assert.NoError(t, f.SetFlagWithSourceIndex("sync-policy", "automated", index1))
assert.NoError(t, f.SetFlagWithSourcePosition("sync-policy", "automated", sourcePosition1))
assert.NotNil(t, f.spec.SyncPolicy.Automated)
f.spec.SyncPolicy = nil
assert.NoError(t, f.SetFlagWithSourceIndex("sync-policy", "automatic", index1))
assert.NoError(t, f.SetFlagWithSourcePosition("sync-policy", "automatic", sourcePosition1))
assert.NotNil(t, f.spec.SyncPolicy.Automated)
})
t.Run("Helm - Index 0", func(t *testing.T) {
assert.NoError(t, f.SetFlagWithSourceIndex("helm-version", "v2", index))
t.Run("Helm - SourcePosition 0", func(t *testing.T) {
assert.NoError(t, f.SetFlagWithSourcePosition("helm-version", "v2", sourcePosition))
assert.Equal(t, len(f.spec.GetSources()), 2)
assert.Equal(t, f.spec.GetSources()[index].Helm.Version, "v2")
assert.Equal(t, f.spec.GetSources()[sourcePosition].Helm.Version, "v2")
})
t.Run("Kustomize", func(t *testing.T) {
assert.NoError(t, f.SetFlagWithSourceIndex("kustomize-replica", "my-deployment=2", index1))
assert.Equal(t, f.spec.Sources[index1-1].Kustomize.Replicas, v1alpha1.KustomizeReplicas{{Name: "my-deployment", Count: intstr.FromInt(2)}})
assert.NoError(t, f.SetFlagWithSourceIndex("kustomize-replica", "my-deployment=4", index2))
assert.Equal(t, f.spec.Sources[index2-1].Kustomize.Replicas, v1alpha1.KustomizeReplicas{{Name: "my-deployment", Count: intstr.FromInt(4)}})
assert.NoError(t, f.SetFlagWithSourcePosition("kustomize-replica", "my-deployment=2", sourcePosition1))
assert.Equal(t, f.spec.Sources[sourcePosition1-1].Kustomize.Replicas, v1alpha1.KustomizeReplicas{{Name: "my-deployment", Count: intstr.FromInt(2)}})
assert.NoError(t, f.SetFlagWithSourcePosition("kustomize-replica", "my-deployment=4", sourcePosition2))
assert.Equal(t, f.spec.Sources[sourcePosition2-1].Kustomize.Replicas, v1alpha1.KustomizeReplicas{{Name: "my-deployment", Count: intstr.FromInt(4)}})
})
t.Run("Helm", func(t *testing.T) {
assert.NoError(t, f.SetFlagWithSourceIndex("helm-version", "v2", index1))
assert.NoError(t, f.SetFlagWithSourceIndex("helm-version", "v3", index2))
assert.NoError(t, f.SetFlagWithSourcePosition("helm-version", "v2", sourcePosition1))
assert.NoError(t, f.SetFlagWithSourcePosition("helm-version", "v3", sourcePosition2))
assert.Equal(t, len(f.spec.GetSources()), 2)
assert.Equal(t, f.spec.GetSources()[index1-1].Helm.Version, "v2")
assert.Equal(t, f.spec.GetSources()[index2-1].Helm.Version, "v3")
assert.Equal(t, f.spec.GetSources()[sourcePosition1-1].Helm.Version, "v2")
assert.Equal(t, f.spec.GetSources()[sourcePosition2-1].Helm.Version, "v3")
})
}

View File

@@ -54,6 +54,7 @@ import (
"github.com/argoproj/argo-cd/v2/reposerver/apiclient"
"github.com/argoproj/argo-cd/v2/util/argo"
argodiff "github.com/argoproj/argo-cd/v2/util/argo/diff"
"github.com/argoproj/argo-cd/v2/util/argo/normalizers"
"github.com/argoproj/argo-cd/v2/util/env"
kubeerrors "k8s.io/apimachinery/pkg/api/errors"
@@ -129,6 +130,7 @@ type ApplicationController struct {
clusterSharding sharding.ClusterShardingCache
projByNameCache sync.Map
applicationNamespaces []string
ignoreNormalizerOpts normalizers.IgnoreNormalizerOpts
// dynamicClusterDistributionEnabled if disabled deploymentInformer is never initialized
dynamicClusterDistributionEnabled bool
@@ -159,6 +161,7 @@ func NewApplicationController(
rateLimiterConfig *ratelimiter.AppControllerRateLimiterConfig,
serverSideDiff bool,
dynamicClusterDistributionEnabled bool,
ignoreNormalizerOpts normalizers.IgnoreNormalizerOpts,
) (*ApplicationController, error) {
log.Infof("appResyncPeriod=%v, appHardResyncPeriod=%v, appResyncJitter=%v", appResyncPeriod, appHardResyncPeriod, appResyncJitter)
db := db.NewDB(namespace, settingsMgr, kubeClientset)
@@ -190,6 +193,7 @@ func NewApplicationController(
projByNameCache: sync.Map{},
applicationNamespaces: applicationNamespaces,
dynamicClusterDistributionEnabled: dynamicClusterDistributionEnabled,
ignoreNormalizerOpts: ignoreNormalizerOpts,
}
if kubectlParallelismLimit > 0 {
ctrl.kubectlSemaphore = semaphore.NewWeighted(kubectlParallelismLimit)
@@ -277,7 +281,7 @@ func NewApplicationController(
}
}
stateCache := statecache.NewLiveStateCache(db, appInformer, ctrl.settingsMgr, kubectl, ctrl.metricsServer, ctrl.handleObjectUpdated, clusterSharding, argo.NewResourceTracking())
appStateManager := NewAppStateManager(db, applicationClientset, repoClientset, namespace, kubectl, ctrl.settingsMgr, stateCache, projInformer, ctrl.metricsServer, argoCache, ctrl.statusRefreshTimeout, argo.NewResourceTracking(), persistResourceHealth, repoErrorGracePeriod, serverSideDiff)
appStateManager := NewAppStateManager(db, applicationClientset, repoClientset, namespace, kubectl, ctrl.settingsMgr, stateCache, projInformer, ctrl.metricsServer, argoCache, ctrl.statusRefreshTimeout, argo.NewResourceTracking(), persistResourceHealth, repoErrorGracePeriod, serverSideDiff, ignoreNormalizerOpts)
ctrl.appInformer = appInformer
ctrl.appLister = appLister
ctrl.projInformer = projInformer
@@ -728,7 +732,7 @@ func (ctrl *ApplicationController) hideSecretData(app *appv1.Application, compar
return nil, fmt.Errorf("error getting cluster cache: %s", err)
}
diffConfig, err := argodiff.NewDiffConfigBuilder().
WithDiffSettings(app.Spec.IgnoreDifferences, resourceOverrides, compareOptions.IgnoreAggregatedRoles).
WithDiffSettings(app.Spec.IgnoreDifferences, resourceOverrides, compareOptions.IgnoreAggregatedRoles, ctrl.ignoreNormalizerOpts).
WithTracking(appLabelKey, trackingMethod).
WithNoCache().
WithLogger(logutils.NewLogrusLogger(logutils.NewWithCurrentConfig())).

View File

@@ -42,6 +42,7 @@ import (
"github.com/argoproj/argo-cd/v2/reposerver/apiclient"
mockrepoclient "github.com/argoproj/argo-cd/v2/reposerver/apiclient/mocks"
"github.com/argoproj/argo-cd/v2/test"
"github.com/argoproj/argo-cd/v2/util/argo/normalizers"
cacheutil "github.com/argoproj/argo-cd/v2/util/cache"
appstatecache "github.com/argoproj/argo-cd/v2/util/cache/appstate"
"github.com/argoproj/argo-cd/v2/util/settings"
@@ -158,9 +159,9 @@ func newFakeController(data *fakeData, repoErr error) *ApplicationController {
nil,
data.applicationNamespaces,
nil,
false,
false,
normalizers.IgnoreNormalizerOpts{},
)
db := &dbmocks.ArgoDB{}
db.On("GetApplicationControllerReplicas").Return(1)

View File

@@ -33,6 +33,7 @@ import (
"github.com/argoproj/argo-cd/v2/pkg/apis/application"
appv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1"
"github.com/argoproj/argo-cd/v2/util/argo"
"github.com/argoproj/argo-cd/v2/util/argo/normalizers"
"github.com/argoproj/argo-cd/v2/util/db"
"github.com/argoproj/argo-cd/v2/util/env"
logutils "github.com/argoproj/argo-cd/v2/util/log"
@@ -197,14 +198,15 @@ type cacheSettings struct {
}
type liveStateCache struct {
db db.ArgoDB
appInformer cache.SharedIndexInformer
onObjectUpdated ObjectUpdatedHandler
kubectl kube.Kubectl
settingsMgr *settings.SettingsManager
metricsServer *metrics.MetricsServer
clusterSharding sharding.ClusterShardingCache
resourceTracking argo.ResourceTracking
db db.ArgoDB
appInformer cache.SharedIndexInformer
onObjectUpdated ObjectUpdatedHandler
kubectl kube.Kubectl
settingsMgr *settings.SettingsManager
metricsServer *metrics.MetricsServer
clusterSharding sharding.ClusterShardingCache
resourceTracking argo.ResourceTracking
ignoreNormalizerOpts normalizers.IgnoreNormalizerOpts
clusters map[string]clustercache.ClusterCache
cacheSettings cacheSettings
@@ -496,7 +498,7 @@ func (c *liveStateCache) getCluster(server string) (clustercache.ClusterCache, e
gvk := un.GroupVersionKind()
if cacheSettings.ignoreResourceUpdatesEnabled && shouldHashManifest(appName, gvk) {
hash, err := generateManifestHash(un, nil, cacheSettings.resourceOverrides)
hash, err := generateManifestHash(un, nil, cacheSettings.resourceOverrides, c.ignoreNormalizerOpts)
if err != nil {
log.Errorf("Failed to generate manifest hash: %v", err)
} else {

View File

@@ -408,8 +408,8 @@ func populateHostNodeInfo(un *unstructured.Unstructured, res *ResourceInfo) {
}
}
func generateManifestHash(un *unstructured.Unstructured, ignores []v1alpha1.ResourceIgnoreDifferences, overrides map[string]v1alpha1.ResourceOverride) (string, error) {
normalizer, err := normalizers.NewIgnoreNormalizer(ignores, overrides)
func generateManifestHash(un *unstructured.Unstructured, ignores []v1alpha1.ResourceIgnoreDifferences, overrides map[string]v1alpha1.ResourceOverride, opts normalizers.IgnoreNormalizerOpts) (string, error) {
normalizer, err := normalizers.NewIgnoreNormalizer(ignores, overrides, opts)
if err != nil {
return "", fmt.Errorf("error creating normalizer: %w", err)
}

View File

@@ -16,6 +16,7 @@ import (
"sigs.k8s.io/yaml"
"github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1"
"github.com/argoproj/argo-cd/v2/util/argo/normalizers"
)
func strToUnstructured(jsonStr string) *unstructured.Unstructured {
@@ -749,7 +750,7 @@ func TestManifestHash(t *testing.T) {
expected := hash(data)
hash, err := generateManifestHash(manifest, ignores, nil)
hash, err := generateManifestHash(manifest, ignores, nil, normalizers.IgnoreNormalizerOpts{})
assert.Equal(t, expected, hash)
assert.Nil(t, err)
}

View File

@@ -36,6 +36,7 @@ import (
"github.com/argoproj/argo-cd/v2/util/app/path"
"github.com/argoproj/argo-cd/v2/util/argo"
argodiff "github.com/argoproj/argo-cd/v2/util/argo/diff"
"github.com/argoproj/argo-cd/v2/util/argo/normalizers"
appstatecache "github.com/argoproj/argo-cd/v2/util/cache/appstate"
"github.com/argoproj/argo-cd/v2/util/db"
"github.com/argoproj/argo-cd/v2/util/gpg"
@@ -118,6 +119,7 @@ type appStateManager struct {
repoErrorCache goSync.Map
repoErrorGracePeriod time.Duration
serverSideDiff bool
ignoreNormalizerOpts normalizers.IgnoreNormalizerOpts
}
// GetRepoObjs will generate the manifests for the given application delegating the
@@ -638,7 +640,7 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *v1
useDiffCache := useDiffCache(noCache, manifestInfos, sources, app, manifestRevisions, m.statusRefreshTimeout, serverSideDiff, logCtx)
diffConfigBuilder := argodiff.NewDiffConfigBuilder().
WithDiffSettings(app.Spec.IgnoreDifferences, resourceOverrides, compareOptions.IgnoreAggregatedRoles).
WithDiffSettings(app.Spec.IgnoreDifferences, resourceOverrides, compareOptions.IgnoreAggregatedRoles, m.ignoreNormalizerOpts).
WithTracking(appLabelKey, string(trackingMethod))
if useDiffCache {
@@ -979,6 +981,7 @@ func NewAppStateManager(
persistResourceHealth bool,
repoErrorGracePeriod time.Duration,
serverSideDiff bool,
ignoreNormalizerOpts normalizers.IgnoreNormalizerOpts,
) AppStateManager {
return &appStateManager{
liveStateCache: liveStateCache,
@@ -996,6 +999,7 @@ func NewAppStateManager(
persistResourceHealth: persistResourceHealth,
repoErrorGracePeriod: repoErrorGracePeriod,
serverSideDiff: serverSideDiff,
ignoreNormalizerOpts: ignoreNormalizerOpts,
}
}

View File

@@ -18,6 +18,7 @@ import (
"github.com/argoproj/argo-cd/v2/reposerver/apiclient"
"github.com/argoproj/argo-cd/v2/test"
"github.com/argoproj/argo-cd/v2/util/argo/diff"
"github.com/argoproj/argo-cd/v2/util/argo/normalizers"
)
func TestPersistRevisionHistory(t *testing.T) {
@@ -330,7 +331,7 @@ func TestNormalizeTargetResources(t *testing.T) {
setup := func(t *testing.T, ignores []v1alpha1.ResourceIgnoreDifferences) *fixture {
t.Helper()
dc, err := diff.NewDiffConfigBuilder().
WithDiffSettings(ignores, nil, true).
WithDiffSettings(ignores, nil, true, normalizers.IgnoreNormalizerOpts{}).
WithNoCache().
Build()
require.NoError(t, err)
@@ -463,7 +464,7 @@ func TestNormalizeTargetResourcesWithList(t *testing.T) {
setupHttpProxy := func(t *testing.T, ignores []v1alpha1.ResourceIgnoreDifferences) *fixture {
t.Helper()
dc, err := diff.NewDiffConfigBuilder().
WithDiffSettings(ignores, nil, true).
WithDiffSettings(ignores, nil, true, normalizers.IgnoreNormalizerOpts{}).
WithNoCache().
Build()
require.NoError(t, err)

View File

@@ -11,10 +11,6 @@ Argo CD administrators can define a certain set of namespaces where `Application
Some manual steps will need to be performed by the Argo CD administrator in order to enable this feature.
!!! note
This feature is considered beta as of now. Some of the implementation details may change over the course of time until it is promoted to a stable status. We will be happy if early adopters use this feature and provide us with bug reports and feedback.
One additional advantage of adopting applications in any namespace is to allow end-users to configure notifications for their Argo CD application in the namespace where Argo CD application is running in. See notifications [namespace based configuration](notifications/index.md#namespace-based-configuration) page for more information.
## Prerequisites

View File

@@ -53,7 +53,7 @@ It can be enabled in any of these ways:
1. Pass `--enable-new-git-file-globbing` to the ApplicationSet controller args.
1. Set `ARGOCD_APPLICATIONSET_CONTROLLER_ENABLE_NEW_GIT_FILE_GLOBBING=true` in the ApplicationSet controller environment variables.
1. Set `applicationsetcontroller.enable.new.git.file.globbing: true` in the Argo CD ConfigMap.
1. Set `applicationsetcontroller.enable.new.git.file.globbing: "true"` in the `argocd-cmd-params-cm` ConfigMap.
Note that the default may change in the future.

View File

@@ -4,21 +4,21 @@
The GitHub notification service changes commit status using [GitHub Apps](https://docs.github.com/en/developers/apps) and requires specifying the following settings:
* `appID` - the app id
* `installationID` - the app installation id
* `privateKey` - the app private key
* `enterpriseBaseURL` - optional URL, e.g. https://git.example.com/
- `appID` - the app id
- `installationID` - the app installation id
- `privateKey` - the app private key
- `enterpriseBaseURL` - optional URL, e.g. https://git.example.com/
## Configuration
1. Create a GitHub Apps using https://github.com/settings/apps/new
2. Change repository permissions to enable write commit statuses and/or deployments and/or pull requests comments
![2](https://user-images.githubusercontent.com/18019529/108397381-3ca57980-725b-11eb-8d17-5b8992dc009e.png)
3. Generate a private key, and download it automatically
![3](https://user-images.githubusercontent.com/18019529/108397926-d4a36300-725b-11eb-83fe-74795c8c3e03.png)
4. Install app to account
5. Store privateKey in `argocd-notifications-secret` Secret and configure GitHub integration
in `argocd-notifications-cm` ConfigMap
1. Change repository permissions to enable write commit statuses and/or deployments and/or pull requests comments
![2](https://user-images.githubusercontent.com/18019529/108397381-3ca57980-725b-11eb-8d17-5b8992dc009e.png)
1. Generate a private key, and download it automatically
![3](https://user-images.githubusercontent.com/18019529/108397926-d4a36300-725b-11eb-83fe-74795c8c3e03.png)
1. Install app to account
1. Store privateKey in `argocd-notifications-secret` Secret and configure GitHub integration
in `argocd-notifications-cm` ConfigMap
```yaml
apiVersion: v1
@@ -77,6 +77,7 @@ template.app-deployed: |
requiredContexts: []
autoMerge: true
transientEnvironment: false
reference: v1.0.0
pullRequestComment:
content: |
Application {{.app.metadata.name}} is now running new version of deployments manifests.
@@ -84,9 +85,11 @@ template.app-deployed: |
```
**Notes**:
- If the message is set to 140 characters or more, it will be truncated.
- If `github.repoURLPath` and `github.revisionPath` are same as above, they can be omitted.
- Automerge is optional and `true` by default for github deployments to ensure the requested ref is up to date with the default branch.
Setting this option to `false` is required if you would like to deploy older refs in your default branch.
For more information see the [GitHub Deployment API Docs](https://docs.github.com/en/rest/deployments/deployments?apiVersion=2022-11-28#create-a-deployment).
- If `github.pullRequestComment.content` is set to 65536 characters or more, it will be truncated.
- Reference is optional. When set, it will be used as the ref to deploy. If not set, the revision will be used as the ref to deploy.

View File

@@ -7,14 +7,23 @@ To be able to send notifications with argocd-notifications you have to create an
3. Click "Teams" in the Menu on the left
4. Select the team that you want to notify
5. In the teams configuration menu select "Integrations"
6. click "Add Integration" in the top right corner
6. Click "Add Integration" in the top right corner
7. Select "API" integration
8. Give your integration a name, copy the "API key" and safe it somewhere for later
9. Make sure the checkboxes for "Create and Update Access" and "enable" are selected, disable the other checkboxes to remove unnecessary permissions
10. Click "Safe Integration" at the bottom
11. Check your browser for the correct server apiURL. If it is "app.opsgenie.com" then use the US/international api url `api.opsgenie.com` in the next step, otherwise use `api.eu.opsgenie.com` (European API).
12. You are finished with configuring Opsgenie. Now you need to configure argocd-notifications. Use the apiUrl, the team name and the apiKey to configure the Opsgenie integration in the `argocd-notifications-secret` secret.
9. Click "Edit" in the integration settings
10. Make sure the checkbox for "Create and Update Access" is selected, disable the other checkboxes to remove unnecessary permissions
11. Click "Save" at the bottom
12. Click "Turn on integration" in the top right corner
13. Check your browser for the correct server apiURL. If it is "app.opsgenie.com" then use the US/international api url `api.opsgenie.com` in the next step, otherwise use `api.eu.opsgenie.com` (European API).
14. You are finished with configuring Opsgenie. Now you need to configure argocd-notifications. Use the apiUrl, the team name and the apiKey to configure the Opsgenie integration in the `argocd-notifications-secret` secret.
15. You can find the example `argocd-notifications-cm` configuration at the below.
| **Option** | **Required** | **Type** | **Description** | **Example** |
| ------------- | ------------ | -------- | -------------------------------------------------------------------------------------------------------- | -------------------------------- |
| `description` | True | `string` | Description field of the alert that is generally used to provide a detailed information about the alert. | `Hello from Argo CD!` |
| `priority` | False | `string` | Priority level of the alert. Possible values are P1, P2, P3, P4 and P5. Default value is P3. | `P1` |
| `alias` | False | `string` | Client-defined identifier of the alert, that is also the key element of Alert De-Duplication. | `Life is too short for no alias` |
| `note` | False | `string` | Additional note that will be added while creating the alert. | `Error from Argo CD!` |
```yaml
apiVersion: v1
@@ -26,4 +35,30 @@ data:
apiUrl: <api-url>
apiKeys:
<your-team>: <integration-api-key>
template.opsgenie: |
message: |
[Argo CD] Application {{.app.metadata.name}} has a problem.
opsgenie:
description: |
Application: {{.app.metadata.name}}
Health Status: {{.app.status.health.status}}
Operation State Phase: {{.app.status.operationState.phase}}
Sync Status: {{.app.status.sync.status}}
priority: P1
alias: {{.app.metadata.name}}
note: Error from Argo CD!
trigger.on-a-problem: |
- description: Application has a problem.
send:
- opsgenie
when: app.status.health.status == 'Degraded' or app.status.operationState.phase in ['Error', 'Failed'] or app.status.sync.status == 'Unknown'
```
16. Add annotation in application yaml file to enable notifications for specific Argo CD app.
```yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
annotations:
notifications.argoproj.io/subscribe.on-a-problem.opsgenie: <your-team>
```

View File

@@ -33,3 +33,12 @@ metadata:
annotations:
notifications.argoproj.io/subscribe.on-sync-succeeded.telegram: -1000000000000
```
If your private chat contains threads, you can optionally specify a thread id by seperating it with a `|`:
```yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
annotations:
notifications.argoproj.io/subscribe.on-sync-succeeded.telegram: -1000000000000|2
```

View File

@@ -15,71 +15,72 @@ argocd-application-controller [flags]
### Options
```
--app-hard-resync int Time period in seconds for application hard resync.
--app-resync int Time period in seconds for application resync. (default 180)
--app-resync-jitter int Maximum time period in seconds to add as a delay jitter for application resync.
--app-state-cache-expiration duration Cache expiration for app state (default 1h0m0s)
--application-namespaces strings List of additional namespaces that applications are allowed to be reconciled from
--as string Username to impersonate for the operation
--as-group stringArray Group to impersonate for the operation, this flag can be repeated to specify multiple groups.
--as-uid string UID to impersonate for the operation
--certificate-authority string Path to a cert file for the certificate authority
--client-certificate string Path to a client certificate file for TLS
--client-key string Path to a client key file for TLS
--cluster string The name of the kubeconfig cluster to use
--context string The name of the kubeconfig context to use
--default-cache-expiration duration Cache expiration default (default 24h0m0s)
--disable-compression If true, opt-out of response compression for all requests to the server
--dynamic-cluster-distribution-enabled Enables dynamic cluster distribution.
--gloglevel int Set the glog logging level
-h, --help help for argocd-application-controller
--insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure
--kubeconfig string Path to a kube config. Only required if out-of-cluster
--kubectl-parallelism-limit int Number of allowed concurrent kubectl fork/execs. Any value less than 1 means no limit. (default 20)
--logformat string Set the logging format. One of: text|json (default "text")
--loglevel string Set the logging level. One of: debug|info|warn|error (default "info")
--metrics-application-labels strings List of Application labels that will be added to the argocd_application_labels metric
--metrics-cache-expiration duration Prometheus metrics cache expiration (disabled by default. e.g. 24h0m0s)
--metrics-port int Start metrics server on given port (default 8082)
-n, --namespace string If present, the namespace scope for this CLI request
--operation-processors int Number of application operation processors (default 10)
--otlp-address string OpenTelemetry collector address to send traces to
--otlp-attrs strings List of OpenTelemetry collector extra attrs when send traces, each attribute is separated by a colon(e.g. key:value)
--otlp-headers stringToString List of OpenTelemetry collector extra headers sent with traces, headers are comma-separated key-value pairs(e.g. key1=value1,key2=value2) (default [])
--otlp-insecure OpenTelemetry collector insecure mode (default true)
--password string Password for basic authentication to the API server
--persist-resource-health Enables storing the managed resources health in the Application CRD (default true)
--proxy-url string If provided, this URL will be used to connect via proxy
--redis string Redis server hostname and port (e.g. argocd-redis:6379).
--redis-ca-certificate string Path to Redis server CA certificate (e.g. /etc/certs/redis/ca.crt). If not specified, system trusted CAs will be used for server certificate validation.
--redis-client-certificate string Path to Redis client certificate (e.g. /etc/certs/redis/client.crt).
--redis-client-key string Path to Redis client key (e.g. /etc/certs/redis/client.crt).
--redis-compress string Enable compression for data sent to Redis with the required compression algorithm. (possible values: gzip, none) (default "gzip")
--redis-insecure-skip-tls-verify Skip Redis server certificate validation.
--redis-use-tls Use TLS when connecting to Redis.
--redisdb int Redis database.
--repo-error-grace-period-seconds int Grace period in seconds for ignoring consecutive errors while communicating with repo server. (default 180)
--repo-server string Repo server address. (default "argocd-repo-server:8081")
--repo-server-plaintext Disable TLS on connections to repo server
--repo-server-strict-tls Whether to use strict validation of the TLS cert presented by the repo server
--repo-server-timeout-seconds int Repo server RPC call timeout seconds. (default 60)
--request-timeout string The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0")
--self-heal-timeout-seconds int Specifies timeout between application self heal attempts (default 5)
--sentinel stringArray Redis sentinel hostname and port (e.g. argocd-redis-ha-announce-0:6379).
--sentinelmaster string Redis sentinel master group name. (default "master")
--server string The address and port of the Kubernetes API server
--server-side-diff-enabled Feature flag to enable ServerSide diff. Default ("false")
--sharding-method string Enables choice of sharding method. Supported sharding methods are : [legacy, round-robin] (default "legacy")
--status-processors int Number of application status processors (default 20)
--tls-server-name string If provided, this name will be used to validate server certificate. If this is not provided, hostname used to contact the server is used.
--token string Bearer token for authentication to the API server
--user string The name of the kubeconfig user to use
--username string Username for basic authentication to the API server
--wq-backoff-factor float Set Workqueue Per Item Rate Limiter Backoff Factor, default is 1.5 (default 1.5)
--wq-basedelay-ns duration Set Workqueue Per Item Rate Limiter Base Delay duration in nanoseconds, default 1000000 (1ms) (default 1ms)
--wq-bucket-qps float Set Workqueue Rate Limiter Bucket QPS, default set to MaxFloat64 which disables the bucket limiter (default 1.7976931348623157e+308)
--wq-bucket-size int Set Workqueue Rate Limiter Bucket Size, default 500 (default 500)
--wq-cooldown-ns duration Set Workqueue Per Item Rate Limiter Cooldown duration in ns, default 0(per item rate limiter disabled)
--wq-maxdelay-ns duration Set Workqueue Per Item Rate Limiter Max Delay duration in nanoseconds, default 1000000000 (1s) (default 1s)
--app-hard-resync int Time period in seconds for application hard resync.
--app-resync int Time period in seconds for application resync. (default 180)
--app-resync-jitter int Maximum time period in seconds to add as a delay jitter for application resync.
--app-state-cache-expiration duration Cache expiration for app state (default 1h0m0s)
--application-namespaces strings List of additional namespaces that applications are allowed to be reconciled from
--as string Username to impersonate for the operation
--as-group stringArray Group to impersonate for the operation, this flag can be repeated to specify multiple groups.
--as-uid string UID to impersonate for the operation
--certificate-authority string Path to a cert file for the certificate authority
--client-certificate string Path to a client certificate file for TLS
--client-key string Path to a client key file for TLS
--cluster string The name of the kubeconfig cluster to use
--context string The name of the kubeconfig context to use
--default-cache-expiration duration Cache expiration default (default 24h0m0s)
--disable-compression If true, opt-out of response compression for all requests to the server
--dynamic-cluster-distribution-enabled Enables dynamic cluster distribution.
--gloglevel int Set the glog logging level
-h, --help help for argocd-application-controller
--ignore-normalizer-jq-execution-timeout-seconds duration Set ignore normalizer JQ execution timeout
--insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure
--kubeconfig string Path to a kube config. Only required if out-of-cluster
--kubectl-parallelism-limit int Number of allowed concurrent kubectl fork/execs. Any value less than 1 means no limit. (default 20)
--logformat string Set the logging format. One of: text|json (default "text")
--loglevel string Set the logging level. One of: debug|info|warn|error (default "info")
--metrics-application-labels strings List of Application labels that will be added to the argocd_application_labels metric
--metrics-cache-expiration duration Prometheus metrics cache expiration (disabled by default. e.g. 24h0m0s)
--metrics-port int Start metrics server on given port (default 8082)
-n, --namespace string If present, the namespace scope for this CLI request
--operation-processors int Number of application operation processors (default 10)
--otlp-address string OpenTelemetry collector address to send traces to
--otlp-attrs strings List of OpenTelemetry collector extra attrs when send traces, each attribute is separated by a colon(e.g. key:value)
--otlp-headers stringToString List of OpenTelemetry collector extra headers sent with traces, headers are comma-separated key-value pairs(e.g. key1=value1,key2=value2) (default [])
--otlp-insecure OpenTelemetry collector insecure mode (default true)
--password string Password for basic authentication to the API server
--persist-resource-health Enables storing the managed resources health in the Application CRD (default true)
--proxy-url string If provided, this URL will be used to connect via proxy
--redis string Redis server hostname and port (e.g. argocd-redis:6379).
--redis-ca-certificate string Path to Redis server CA certificate (e.g. /etc/certs/redis/ca.crt). If not specified, system trusted CAs will be used for server certificate validation.
--redis-client-certificate string Path to Redis client certificate (e.g. /etc/certs/redis/client.crt).
--redis-client-key string Path to Redis client key (e.g. /etc/certs/redis/client.crt).
--redis-compress string Enable compression for data sent to Redis with the required compression algorithm. (possible values: gzip, none) (default "gzip")
--redis-insecure-skip-tls-verify Skip Redis server certificate validation.
--redis-use-tls Use TLS when connecting to Redis.
--redisdb int Redis database.
--repo-error-grace-period-seconds int Grace period in seconds for ignoring consecutive errors while communicating with repo server. (default 180)
--repo-server string Repo server address. (default "argocd-repo-server:8081")
--repo-server-plaintext Disable TLS on connections to repo server
--repo-server-strict-tls Whether to use strict validation of the TLS cert presented by the repo server
--repo-server-timeout-seconds int Repo server RPC call timeout seconds. (default 60)
--request-timeout string The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0")
--self-heal-timeout-seconds int Specifies timeout between application self heal attempts (default 5)
--sentinel stringArray Redis sentinel hostname and port (e.g. argocd-redis-ha-announce-0:6379).
--sentinelmaster string Redis sentinel master group name. (default "master")
--server string The address and port of the Kubernetes API server
--server-side-diff-enabled Feature flag to enable ServerSide diff. Default ("false")
--sharding-method string Enables choice of sharding method. Supported sharding methods are : [legacy, round-robin] (default "legacy")
--status-processors int Number of application status processors (default 20)
--tls-server-name string If provided, this name will be used to validate server certificate. If this is not provided, hostname used to contact the server is used.
--token string Bearer token for authentication to the API server
--user string The name of the kubeconfig user to use
--username string Username for basic authentication to the API server
--wq-backoff-factor float Set Workqueue Per Item Rate Limiter Backoff Factor, default is 1.5 (default 1.5)
--wq-basedelay-ns duration Set Workqueue Per Item Rate Limiter Base Delay duration in nanoseconds, default 1000000 (1ms) (default 1ms)
--wq-bucket-qps float Set Workqueue Rate Limiter Bucket QPS, default set to MaxFloat64 which disables the bucket limiter (default 1.7976931348623157e+308)
--wq-bucket-size int Set Workqueue Rate Limiter Bucket Size, default 500 (default 500)
--wq-cooldown-ns duration Set Workqueue Per Item Rate Limiter Cooldown duration in ns, default 0(per item rate limiter disabled)
--wq-maxdelay-ns duration Set Workqueue Per Item Rate Limiter Max Delay duration in nanoseconds, default 1000000000 (1s) (default 1s)
```

View File

@@ -1,6 +1,5 @@
| Argo CD version | Kubernetes versions |
|-----------------|---------------------|
| 2.7 | v1.26, v1.25, v1.24, v1.23 |
| 2.6 | v1.24, v1.23, v1.22 |
| 2.5 | v1.24, v1.23, v1.22 |
| 2.11 | v1.29, v1.28, v1.27, v1.26, v1.25 |
| 2.10 | v1.28, v1.27, v1.26, v1.25 |
| 2.9 | v1.28, v1.27, v1.26, v1.25 |

View File

@@ -11,84 +11,9 @@ argocd admin [flags]
### Examples
```
# List all clusters
$ argocd admin cluster list
# Add a new cluster
$ argocd admin cluster add my-cluster --name my-cluster --in-cluster-context
# Remove a cluster
argocd admin cluster remove my-cluster
# List all projects
$ argocd admin project list
# Create a new project
$argocd admin project create my-project --src-namespace my-source-namespace --dest-namespace my-dest-namespace
# Update a project
$ argocd admin project update my-project --src-namespace my-updated-source-namespace --dest-namespace my-updated-dest-namespace
# Delete a project
$ argocd admin project delete my-project
# List all settings
$ argocd admin settings list
# Get the current settings
$ argocd admin settings get
# Update settings
$ argocd admin settings update --repository.resync --value 15
# List all applications
$ argocd admin app list
# Get application details
$ argocd admin app get my-app
# Sync an application
$ argocd admin app sync my-app
# Pause an application
$ argocd admin app pause my-app
# Resume an application
$ argocd admin app resume my-app
# List all repositories
$ argocd admin repo list
# Add a repository
$ argocd admin repo add https://github.com/argoproj/my-repo.git
# Remove a repository
$ argocd admin repo remove https://github.com/argoproj/my-repo.git
# Import an application from a YAML file
$ argocd admin app import -f my-app.yaml
# Export an application to a YAML file
$ argocd admin app export my-app -o my-exported-app.yaml
# Access the Argo CD web UI
$ argocd admin dashboard
# List notifications
$ argocd admin notification list
# Get notification details
$ argocd admin notification get my-notification
# Create a new notification
$ argocd admin notification create my-notification -f notification-config.yaml
# Update a notification
$ argocd admin notification update my-notification -f updated-notification-config.yaml
# Delete a notification
$ argocd admin notification delete my-notification
# Reset the initial admin password
$ argocd admin initial-password reset

View File

@@ -11,32 +11,33 @@ argocd admin app get-reconcile-results PATH [flags]
### Options
```
--as string Username to impersonate for the operation
--as-group stringArray Group to impersonate for the operation, this flag can be repeated to specify multiple groups.
--as-uid string UID to impersonate for the operation
--certificate-authority string Path to a cert file for the certificate authority
--client-certificate string Path to a client certificate file for TLS
--client-key string Path to a client key file for TLS
--cluster string The name of the kubeconfig cluster to use
--context string The name of the kubeconfig context to use
--disable-compression If true, opt-out of response compression for all requests to the server
-h, --help help for get-reconcile-results
--insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure
--kubeconfig string Path to a kube config. Only required if out-of-cluster
--l string Label selector
-n, --namespace string If present, the namespace scope for this CLI request
--o string Output format (yaml|json) (default "yaml")
--password string Password for basic authentication to the API server
--proxy-url string If provided, this URL will be used to connect via proxy
--refresh If set to true then recalculates apps reconciliation
--repo-server string Repo server address.
--request-timeout string The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0")
--server string The address and port of the Kubernetes API server
--server-side-diff If set to "true" will use server-side diff while comparing resources. Default ("false")
--tls-server-name string If provided, this name will be used to validate server certificate. If this is not provided, hostname used to contact the server is used.
--token string Bearer token for authentication to the API server
--user string The name of the kubeconfig user to use
--username string Username for basic authentication to the API server
--as string Username to impersonate for the operation
--as-group stringArray Group to impersonate for the operation, this flag can be repeated to specify multiple groups.
--as-uid string UID to impersonate for the operation
--certificate-authority string Path to a cert file for the certificate authority
--client-certificate string Path to a client certificate file for TLS
--client-key string Path to a client key file for TLS
--cluster string The name of the kubeconfig cluster to use
--context string The name of the kubeconfig context to use
--disable-compression If true, opt-out of response compression for all requests to the server
-h, --help help for get-reconcile-results
--ignore-normalizer-jq-execution-timeout duration Set ignore normalizer JQ execution timeout (default 1s)
--insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure
--kubeconfig string Path to a kube config. Only required if out-of-cluster
--l string Label selector
-n, --namespace string If present, the namespace scope for this CLI request
--o string Output format (yaml|json) (default "yaml")
--password string Password for basic authentication to the API server
--proxy-url string If provided, this URL will be used to connect via proxy
--refresh If set to true then recalculates apps reconciliation
--repo-server string Repo server address.
--request-timeout string The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0")
--server string The address and port of the Kubernetes API server
--server-side-diff If set to "true" will use server-side diff while comparing resources. Default ("false")
--tls-server-name string If provided, this name will be used to validate server certificate. If this is not provided, hostname used to contact the server is used.
--token string Bearer token for authentication to the API server
--user string The name of the kubeconfig user to use
--username string Username for basic authentication to the API server
```
### Options inherited from parent commands

View File

@@ -22,7 +22,8 @@ argocd admin settings resource-overrides ignore-resource-updates ./deploy.yaml -
### Options
```
-h, --help help for ignore-resource-updates
-h, --help help for ignore-resource-updates
--ignore-normalizer-jq-execution-timeout duration Set ignore normalizer JQ execution timeout (default 1s)
```
### Options inherited from parent commands

View File

@@ -91,7 +91,7 @@ argocd app [flags]
* [argocd app manifests](argocd_app_manifests.md) - Print manifests of an application
* [argocd app patch](argocd_app_patch.md) - Patch application
* [argocd app patch-resource](argocd_app_patch-resource.md) - Patch resource in an application
* [argocd app remove-source](argocd_app_remove-source.md) - Remove a source from multiple sources application. Index starts with 1. Default value is -1.
* [argocd app remove-source](argocd_app_remove-source.md) - Remove a source from multiple sources application. Counting starts with 1. Default value is -1.
* [argocd app resources](argocd_app_resources.md) - List resource of application
* [argocd app rollback](argocd_app_rollback.md) - Rollback application to a previous deployed version by History ID, omitted will Rollback to the previous version
* [argocd app set](argocd_app_set.md) - Set application parameters

View File

@@ -18,18 +18,19 @@ argocd app diff APPNAME [flags]
### Options
```
-N, --app-namespace string Only render the difference in namespace
--exit-code Return non-zero exit code when there is a diff (default true)
--hard-refresh Refresh application data as well as target manifests cache
-h, --help help for diff
--local string Compare live app to a local manifests
--local-include stringArray Used with --server-side-generate, specify patterns of filenames to send. Matching is based on filename and not path. (default [*.yaml,*.yml,*.json])
--local-repo-root string Path to the repository root. Used together with --local allows setting the repository root (default "/")
--refresh Refresh application data when retrieving
--revision string Compare live app to a particular revision
--revisions stringArray Show manifests at specific revisions for the index of sources in source-indexes
--server-side-generate Used with --local, this will send your manifests to the server for diffing
--source-indexes int64Slice List of source indexes. Default is empty array. Indexes start at 1. (default [])
-N, --app-namespace string Only render the difference in namespace
--exit-code Return non-zero exit code when there is a diff (default true)
--hard-refresh Refresh application data as well as target manifests cache
-h, --help help for diff
--ignore-normalizer-jq-execution-timeout duration Set ignore normalizer JQ execution timeout (default 1s)
--local string Compare live app to a local manifests
--local-include stringArray Used with --server-side-generate, specify patterns of filenames to send. Matching is based on filename and not path. (default [*.yaml,*.yml,*.json])
--local-repo-root string Path to the repository root. Used together with --local allows setting the repository root (default "/")
--refresh Refresh application data when retrieving
--revision string Compare live app to a particular revision
--revisions stringArray Show manifests at specific revisions for source position in source-positions
--server-side-generate Used with --local, this will send your manifests to the server for diffing
--source-positions int64Slice List of source positions. Default is empty array. Counting start at 1. (default [])
```
### Options inherited from parent commands

View File

@@ -18,19 +18,19 @@ argocd app manifests APPNAME [flags]
argocd app manifests my-app --revision 0.0.1
# Get manifests for a multi-source application at specific revisions for specific sources
argocd app manifests my-app --revisions 0.0.1 --source-indexes 1 --revisions 0.0.2 --source-indexes 2
argocd app manifests my-app --revisions 0.0.1 --source-positions 1 --revisions 0.0.2 --source-positions 2
```
### Options
```
-h, --help help for manifests
--local string If set, show locally-generated manifests. Value is the absolute path to app manifests within the manifest repo. Example: '/home/username/apps/env/app-1'.
--local-repo-root string Path to the local repository root. Used together with --local allows setting the repository root. Example: '/home/username/apps'. (default ".")
--revision string Show manifests at a specific revision
--revisions stringArray Show manifests at specific revisions for the index of sources in source-indexes
--source string Source of manifests. One of: live|git (default "git")
--source-indexes int64Slice List of source indexes. Default is empty array. Indexes start at 1. (default [])
-h, --help help for manifests
--local string If set, show locally-generated manifests. Value is the absolute path to app manifests within the manifest repo. Example: '/home/username/apps/env/app-1'.
--local-repo-root string Path to the local repository root. Used together with --local allows setting the repository root. Example: '/home/username/apps'. (default ".")
--revision string Show manifests at a specific revision
--revisions stringArray Show manifests at specific revisions for the source at position in source-positions
--source string Source of manifests. One of: live|git (default "git")
--source-positions int64Slice List of source positions. Default is empty array. Counting start at 1. (default [])
```
### Options inherited from parent commands

View File

@@ -2,7 +2,7 @@
## argocd app remove-source
Remove a source from multiple sources application. Index starts with 1. Default value is -1.
Remove a source from multiple sources application. Counting starts with 1. Default value is -1.
```
argocd app remove-source APPNAME [flags]
@@ -11,8 +11,8 @@ argocd app remove-source APPNAME [flags]
### Examples
```
# Remove the source at index 1 from application's sources. Index starts at 1.
argocd app remove-source myapplication --source-index 1
# Remove the source at position 1 from application's sources. Counting starts at 1.
argocd app remove-source myapplication --source-position 1
```
### Options
@@ -20,7 +20,7 @@ argocd app remove-source APPNAME [flags]
```
-N, --app-namespace string Namespace of the target application where the source will be appended
-h, --help help for remove-source
--source-index int Index of the source from the list of sources of the app. Index starts from 1. (default -1)
--source-position int Position of the source from the list of sources of the app. Counting starts at 1. (default -1)
```
### Options inherited from parent commands

View File

@@ -23,8 +23,8 @@ argocd app set APPNAME [flags]
# Set and override application parameters with a parameter file
argocd app set my-app --parameter-file path/to/parameter-file.yaml
# Set and override application parameters for a source at index 1 under spec.sources of app my-app. source-index starts at 1.
argocd app set my-app --source-index 1 --repo https://github.com/argoproj/argocd-example-apps.git
# Set and override application parameters for a source at position 1 under spec.sources of app my-app. source-position starts at 1.
argocd app set my-app --source-position 1 --repo https://github.com/argoproj/argocd-example-apps.git
# Set application parameters and specify the namespace
argocd app set my-app --parameter key1=value1 --parameter key2=value2 --namespace my-namespace
@@ -79,7 +79,7 @@ argocd app set APPNAME [flags]
--revision string The tracking source branch, tag, commit or Helm chart version the application will sync to
--revision-history-limit int How many items to keep in revision history (default 10)
--self-heal Set self healing when sync is automated
--source-index int Index of the source from the list of sources of the app. Index starts at 1. (default -1)
--source-position int Position of the source from the list of sources of the app. Counting starts at 1. (default -1)
--sync-option Prune=false Add or remove a sync option, e.g add Prune=false. Remove using `!` prefix, e.g. `!Prune=false`
--sync-policy string Set the sync policy (one of: manual (aliases of manual: none), automated (aliases of automated: auto, automatic))
--sync-retry-backoff-duration duration Sync retry backoff base duration. Input needs to be a duration (e.g. 2m, 1h) (default 5s)

View File

@@ -24,6 +24,9 @@ argocd app sync [APPNAME... | -l selector | --project project-name] [flags]
argocd app sync -l '!app.kubernetes.io/instance'
argocd app sync -l 'app.kubernetes.io/instance notin (my-app,other-app)'
# Sync a multi-source application for specific revision of specific sources
argocd app manifests my-app --revisions 0.0.1 --source-positions 1 --revisions 0.0.2 --source-positions 2
# Sync a specific resource
# Resource should be formatted as GROUP:KIND:NAME. If no GROUP is specified then :KIND:NAME
argocd app sync my-app --resource :Service:my-service
@@ -38,32 +41,35 @@ argocd app sync [APPNAME... | -l selector | --project project-name] [flags]
### Options
```
-N, --app-namespace string Only sync an application in namespace
--apply-out-of-sync-only Sync only out-of-sync resources
--assumeYes Assume yes as answer for all user queries or prompts
--async Do not wait for application to sync before continuing
--dry-run Preview apply without affecting cluster
--force Use a force apply
-h, --help help for sync
--info stringArray A list of key-value pairs during sync process. These infos will be persisted in app.
--label stringArray Sync only specific resources with a label. This option may be specified repeatedly.
--local string Path to a local directory. When this flag is present no git queries will be made
--local-repo-root string Path to the repository root. Used together with --local allows setting the repository root (default "/")
-o, --output string Output format. One of: json|yaml|wide|tree|tree=detailed (default "wide")
--preview-changes Preview difference against the target and live state before syncing app and wait for user confirmation
--project stringArray Sync apps that belong to the specified projects. This option may be specified repeatedly.
--prune Allow deleting unexpected resources
--replace Use a kubectl create/replace instead apply
--resource stringArray Sync only specific resources as GROUP:KIND:NAME or !GROUP:KIND:NAME. Fields may be blank and '*' can be used. This option may be specified repeatedly
--retry-backoff-duration duration Retry backoff base duration. Input needs to be a duration (e.g. 2m, 1h) (default 5s)
--retry-backoff-factor int Factor multiplies the base duration after each failed retry (default 2)
--retry-backoff-max-duration duration Max retry backoff duration. Input needs to be a duration (e.g. 2m, 1h) (default 3m0s)
--retry-limit int Max number of allowed sync retries
--revision string Sync to a specific revision. Preserves parameter overrides
-l, --selector string Sync apps that match this label. Supports '=', '==', '!=', in, notin, exists & not exists. Matching apps must satisfy all of the specified label constraints.
--server-side Use server-side apply while syncing the application
--strategy string Sync strategy (one of: apply|hook)
--timeout uint Time out after this many seconds
-N, --app-namespace string Only sync an application in namespace
--apply-out-of-sync-only Sync only out-of-sync resources
--assumeYes Assume yes as answer for all user queries or prompts
--async Do not wait for application to sync before continuing
--dry-run Preview apply without affecting cluster
--force Use a force apply
-h, --help help for sync
--ignore-normalizer-jq-execution-timeout duration Set ignore normalizer JQ execution timeout (default 1s)
--info stringArray A list of key-value pairs during sync process. These infos will be persisted in app.
--label stringArray Sync only specific resources with a label. This option may be specified repeatedly.
--local string Path to a local directory. When this flag is present no git queries will be made
--local-repo-root string Path to the repository root. Used together with --local allows setting the repository root (default "/")
-o, --output string Output format. One of: json|yaml|wide|tree|tree=detailed (default "wide")
--preview-changes Preview difference against the target and live state before syncing app and wait for user confirmation
--project stringArray Sync apps that belong to the specified projects. This option may be specified repeatedly.
--prune Allow deleting unexpected resources
--replace Use a kubectl create/replace instead apply
--resource stringArray Sync only specific resources as GROUP:KIND:NAME or !GROUP:KIND:NAME. Fields may be blank and '*' can be used. This option may be specified repeatedly
--retry-backoff-duration duration Retry backoff base duration. Input needs to be a duration (e.g. 2m, 1h) (default 5s)
--retry-backoff-factor int Factor multiplies the base duration after each failed retry (default 2)
--retry-backoff-max-duration duration Max retry backoff duration. Input needs to be a duration (e.g. 2m, 1h) (default 3m0s)
--retry-limit int Max number of allowed sync retries
--revision string Sync to a specific revision. Preserves parameter overrides
--revisions stringArray Show manifests at specific revisions for source position in source-positions
-l, --selector string Sync apps that match this label. Supports '=', '==', '!=', in, notin, exists & not exists. Matching apps must satisfy all of the specified label constraints.
--server-side Use server-side apply while syncing the application
--source-positions int64Slice List of source positions. Default is empty array. Counting start at 1. (default [])
--strategy string Sync strategy (one of: apply|hook)
--timeout uint Time out after this many seconds
```
### Options inherited from parent commands

View File

@@ -17,8 +17,8 @@ argocd app unset APPNAME parameters [flags]
# Unset kustomize override suffix
argocd app unset my-app --namesuffix
# Unset kustomize override suffix for source at index 1 under spec.sources of app my-app. source-index starts at 1.
argocd app unset my-app --source-index 1 --namesuffix
# Unset kustomize override suffix for source at position 1 under spec.sources of app my-app. source-position starts at 1.
argocd app unset my-app --source-position 1 --namesuffix
# Unset parameter override
argocd app unset my-app -p COMPONENT=PARAM
@@ -40,7 +40,7 @@ argocd app unset APPNAME parameters [flags]
--pass-credentials Unset passCredentials
--plugin-env stringArray Unset plugin env variables (e.g --plugin-env name)
--ref Unset ref on the source
--source-index int Index of the source from the list of sources of the app. Index starts at 1. (default -1)
--source-position int Position of the source from the list of sources of the app. Counting starts at 1. (default -1)
--values stringArray Unset one or more Helm values files
--values-literal Unset literal Helm values block
```

View File

@@ -185,3 +185,16 @@ The list of supported Kubernetes types is available in [diffing_known_types.txt]
* `core/Quantity`
* `meta/v1/duration`
### JQ Path expression timeout
By default, the evaluation of a JQPathExpression is limited to one second. If you encounter a "JQ patch execution timed out" error message due to a complex JQPathExpression that requires more time to evaluate, you can extend the timeout period by configuring the `ignore.normalizer.jq.timeout` setting within the `argocd-cmd-params-cm` ConfigMap.
```yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-cmd-params-cm
data:
ignore.normalizer.jq.timeout: "5s"

12
go.mod
View File

@@ -14,7 +14,7 @@ require (
github.com/alicebob/miniredis/v2 v2.30.4
github.com/antonmedv/expr v1.15.2
github.com/argoproj/gitops-engine v0.7.1-0.20240124052710-5fd9f449e757
github.com/argoproj/notifications-engine v0.4.1-0.20240206192038-2daee6022f41
github.com/argoproj/notifications-engine v0.4.1-0.20240403133627-f48567108f01
github.com/argoproj/pkg v0.13.7-0.20230626144333-d56162821bd1
github.com/aws/aws-sdk-go v1.50.8
github.com/bmatcuk/doublestar/v4 v4.6.0
@@ -22,6 +22,7 @@ require (
github.com/bradleyfalzon/ghinstallation/v2 v2.6.0
github.com/casbin/casbin/v2 v2.77.2
github.com/cespare/xxhash/v2 v2.2.0
github.com/chainguard-dev/git-urls v1.0.2
github.com/coreos/go-oidc/v3 v3.6.0
github.com/cyphar/filepath-securejoin v0.2.4
github.com/dustin/go-humanize v1.0.1
@@ -75,7 +76,6 @@ require (
github.com/spf13/pflag v1.0.5
github.com/stretchr/testify v1.8.4
github.com/valyala/fasttemplate v1.2.2
github.com/whilp/git-urls v1.0.0
github.com/xanzy/go-gitlab v0.91.1
github.com/yuin/gopher-lua v1.1.0
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.42.0
@@ -106,7 +106,7 @@ require (
oras.land/oras-go/v2 v2.3.0
sigs.k8s.io/controller-runtime v0.14.7
sigs.k8s.io/structured-merge-diff/v4 v4.4.1
sigs.k8s.io/yaml v1.3.0
sigs.k8s.io/yaml v1.4.0
)
require (
@@ -252,7 +252,7 @@ require (
github.com/shopspring/decimal v1.2.0 // indirect
github.com/skeema/knownhosts v1.2.1 // indirect
github.com/slack-go/slack v0.12.2 // indirect
github.com/spf13/cast v1.5.1 // indirect
github.com/spf13/cast v1.6.0 // indirect
github.com/stretchr/objx v0.5.0 // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect
github.com/vmihailenco/go-tinylfu v0.2.2 // indirect
@@ -270,7 +270,7 @@ require (
golang.org/x/net v0.19.0
golang.org/x/sys v0.17.0 // indirect
golang.org/x/text v0.14.0 // indirect
golang.org/x/time v0.3.0
golang.org/x/time v0.5.0
golang.org/x/tools v0.13.0 // indirect
gomodules.xyz/envconfig v1.3.1-0.20190308184047-426f31af0d45 // indirect
gomodules.xyz/jsonpatch/v2 v2.2.0 // indirect
@@ -295,6 +295,8 @@ replace (
// https://github.com/golang/go/issues/33546#issuecomment-519656923
github.com/go-check/check => github.com/go-check/check v0.0.0-20180628173108-788fd7840127
github.com/go-telegram-bot-api/telegram-bot-api/v5 => github.com/OvyFlash/telegram-bot-api/v5 v5.0.0-20240108230938-63e5c59035bf
github.com/golang/protobuf => github.com/golang/protobuf v1.4.2
github.com/grpc-ecosystem/grpc-gateway => github.com/grpc-ecosystem/grpc-gateway v1.16.0

22
go.sum
View File

@@ -654,6 +654,8 @@ github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migc
github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM=
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/OvyFlash/telegram-bot-api/v5 v5.0.0-20240108230938-63e5c59035bf h1:a7VKhbjKYPO8twGy/1AxMpM2Fp0qT7bf25fmCVMVu4s=
github.com/OvyFlash/telegram-bot-api/v5 v5.0.0-20240108230938-63e5c59035bf/go.mod h1:A2S0CWkNylc2phvKXWBBdD3K0iGnDBGbzRpISP2zBl8=
github.com/PagerDuty/go-pagerduty v1.7.0 h1:S1NcMKECxT5hJwV4VT+QzeSsSiv4oWl1s2821dUqG/8=
github.com/PagerDuty/go-pagerduty v1.7.0/go.mod h1:PuFyJKRz1liIAH4h5KVXVD18Obpp1ZXRdxHvmGXooro=
github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8/go.mod h1:I0gYDMZ6Z5GRU7l58bNFSkPTFN6Yl12dsUlAZ8xy98g=
@@ -696,8 +698,8 @@ github.com/apache/thrift v0.16.0/go.mod h1:PHK3hniurgQaNMZYaCLEqXKsYK8upmhPbmdP2
github.com/appscode/go v0.0.0-20191119085241-0887d8ec2ecc/go.mod h1:OawnOmAL4ZX3YaPdN+8HTNwBveT1jMsqP74moa9XUbE=
github.com/argoproj/gitops-engine v0.7.1-0.20240124052710-5fd9f449e757 h1:5fKAhTQcTBom0vin56cz/UTPx2GMuvdb+lJRAUOPbHA=
github.com/argoproj/gitops-engine v0.7.1-0.20240124052710-5fd9f449e757/go.mod h1:gWE8uROi7hIkWGNAVM+8FWkMfo0vZ03SLx/aFw/DBzg=
github.com/argoproj/notifications-engine v0.4.1-0.20240206192038-2daee6022f41 h1:PQE8LbcbRHdtnQzeEWwVU2QHXACKOA30yS3No5HSoTQ=
github.com/argoproj/notifications-engine v0.4.1-0.20240206192038-2daee6022f41/go.mod h1:TsyusmXQWIL0ST7YMRG/ered7WlWDmbmnPpXnS2LJmM=
github.com/argoproj/notifications-engine v0.4.1-0.20240403133627-f48567108f01 h1:/V8+HM0VPPTrdjTwUrkIj5a+SjaU//tJwfIXJ1QAOvg=
github.com/argoproj/notifications-engine v0.4.1-0.20240403133627-f48567108f01/go.mod h1:N0A4sEws2soZjEpY4hgZpQS8mRIEw6otzwfkgc3g9uQ=
github.com/argoproj/pkg v0.13.7-0.20230626144333-d56162821bd1 h1:qsHwwOJ21K2Ao0xPju1sNuqphyMnMYkyB3ZLoLtxWpo=
github.com/argoproj/pkg v0.13.7-0.20230626144333-d56162821bd1/go.mod h1:CZHlkyAD1/+FbEn6cB2DQTj48IoLGvEYsWEvtzP3238=
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
@@ -900,8 +902,8 @@ github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzP
github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4=
github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20=
github.com/frankban/quicktest v1.2.2/go.mod h1:Qh/WofXFeiAFII1aEBu529AtJo6Zg2VHscnEsbBnJ20=
github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY=
github.com/frankban/quicktest v1.14.4/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
@@ -1015,8 +1017,6 @@ github.com/go-redis/cache/v9 v9.0.0/go.mod h1:cMwi1N8ASBOufbIvk7cdXe2PbPjK/WMRL9
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
github.com/go-telegram-bot-api/telegram-bot-api/v5 v5.5.1 h1:wG8n/XJQ07TmjbITcGiUaOtXxdrINDz1b0J1w0SzqDc=
github.com/go-telegram-bot-api/telegram-bot-api/v5 v5.5.1/go.mod h1:A2S0CWkNylc2phvKXWBBdD3K0iGnDBGbzRpISP2zBl8=
github.com/go-test/deep v1.0.4 h1:u2CU3YKy9I2pmu9pX0eq50wCgjfGIt539SqR7FbHiho=
github.com/go-test/deep v1.0.4/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0=
@@ -1647,8 +1647,8 @@ github.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY52
github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
github.com/spf13/afero v1.9.2/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcDf8Y=
github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cast v1.5.1 h1:R+kOtfhWQE6TVQzY+4D7wJLBgkdVasCEFxSUBYBYIlA=
github.com/spf13/cast v1.5.1/go.mod h1:b9PdjNptOpzXr7Rq1q9gJML/2cdGQAo69NKzQ10KN48=
github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0=
github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I=
github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0=
@@ -2179,8 +2179,9 @@ golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxb
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20220922220347-f3bd1da661af/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.1.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
@@ -2719,6 +2720,7 @@ sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+s
sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08=
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo=
sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8=
sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E=
sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY=
sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU=

View File

@@ -197,6 +197,12 @@ spec:
name: argocd-cmd-params-cm
key: controller.diff.server.side
optional: true
- name: ARGOCD_IGNORE_NORMALIZER_JQ_TIMEOUT
valueFrom:
configMapKeyRef:
name: argocd-cmd-params-cm
key: controller.ignore.normalizer.jq.timeout
optional: true
image: quay.io/argoproj/argocd:latest
imagePullPolicy: Always
name: argocd-application-controller

View File

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

View File

@@ -21184,7 +21184,7 @@ spec:
key: applicationsetcontroller.enable.scm.providers
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:latest
image: quay.io/argoproj/argocd:v2.11.0-rc3
imagePullPolicy: Always
name: argocd-applicationset-controller
ports:
@@ -21514,7 +21514,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:v2.11.0-rc3
imagePullPolicy: Always
livenessProbe:
failureThreshold: 3
@@ -21566,7 +21566,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /var/run/argocd/argocd-cmp-server
image: quay.io/argoproj/argocd:latest
image: quay.io/argoproj/argocd:v2.11.0-rc3
name: copyutil
securityContext:
allowPrivilegeEscalation: false
@@ -21827,7 +21827,13 @@ spec:
key: controller.diff.server.side
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:latest
- name: ARGOCD_IGNORE_NORMALIZER_JQ_TIMEOUT
valueFrom:
configMapKeyRef:
key: controller.ignore.normalizer.jq.timeout
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.11.0-rc3
imagePullPolicy: Always
name: argocd-application-controller
ports:

View File

@@ -12,4 +12,4 @@ resources:
images:
- name: quay.io/argoproj/argocd
newName: quay.io/argoproj/argocd
newTag: latest
newTag: v2.11.0-rc3

View File

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

View File

@@ -22547,7 +22547,7 @@ spec:
key: applicationsetcontroller.enable.scm.providers
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:latest
image: quay.io/argoproj/argocd:v2.11.0-rc3
imagePullPolicy: Always
name: argocd-applicationset-controller
ports:
@@ -22670,7 +22670,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /shared/argocd-dex
image: quay.io/argoproj/argocd:latest
image: quay.io/argoproj/argocd:v2.11.0-rc3
imagePullPolicy: Always
name: copyutil
securityContext:
@@ -22752,7 +22752,7 @@ spec:
key: notificationscontroller.selfservice.enabled
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:latest
image: quay.io/argoproj/argocd:v2.11.0-rc3
imagePullPolicy: Always
livenessProbe:
tcpSocket:
@@ -23113,7 +23113,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:v2.11.0-rc3
imagePullPolicy: Always
livenessProbe:
failureThreshold: 3
@@ -23165,7 +23165,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /var/run/argocd/argocd-cmp-server
image: quay.io/argoproj/argocd:latest
image: quay.io/argoproj/argocd:v2.11.0-rc3
name: copyutil
securityContext:
allowPrivilegeEscalation: false
@@ -23484,7 +23484,7 @@ spec:
key: server.api.content.types
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:latest
image: quay.io/argoproj/argocd:v2.11.0-rc3
imagePullPolicy: Always
livenessProbe:
httpGet:
@@ -23772,7 +23772,13 @@ spec:
key: controller.diff.server.side
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:latest
- name: ARGOCD_IGNORE_NORMALIZER_JQ_TIMEOUT
valueFrom:
configMapKeyRef:
key: controller.ignore.normalizer.jq.timeout
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.11.0-rc3
imagePullPolicy: Always
name: argocd-application-controller
ports:

View File

@@ -1668,7 +1668,7 @@ spec:
key: applicationsetcontroller.enable.scm.providers
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:latest
image: quay.io/argoproj/argocd:v2.11.0-rc3
imagePullPolicy: Always
name: argocd-applicationset-controller
ports:
@@ -1791,7 +1791,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /shared/argocd-dex
image: quay.io/argoproj/argocd:latest
image: quay.io/argoproj/argocd:v2.11.0-rc3
imagePullPolicy: Always
name: copyutil
securityContext:
@@ -1873,7 +1873,7 @@ spec:
key: notificationscontroller.selfservice.enabled
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:latest
image: quay.io/argoproj/argocd:v2.11.0-rc3
imagePullPolicy: Always
livenessProbe:
tcpSocket:
@@ -2234,7 +2234,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:v2.11.0-rc3
imagePullPolicy: Always
livenessProbe:
failureThreshold: 3
@@ -2286,7 +2286,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /var/run/argocd/argocd-cmp-server
image: quay.io/argoproj/argocd:latest
image: quay.io/argoproj/argocd:v2.11.0-rc3
name: copyutil
securityContext:
allowPrivilegeEscalation: false
@@ -2605,7 +2605,7 @@ spec:
key: server.api.content.types
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:latest
image: quay.io/argoproj/argocd:v2.11.0-rc3
imagePullPolicy: Always
livenessProbe:
httpGet:
@@ -2893,7 +2893,13 @@ spec:
key: controller.diff.server.side
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:latest
- name: ARGOCD_IGNORE_NORMALIZER_JQ_TIMEOUT
valueFrom:
configMapKeyRef:
key: controller.ignore.normalizer.jq.timeout
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.11.0-rc3
imagePullPolicy: Always
name: argocd-application-controller
ports:

View File

@@ -21642,7 +21642,7 @@ spec:
key: applicationsetcontroller.enable.scm.providers
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:latest
image: quay.io/argoproj/argocd:v2.11.0-rc3
imagePullPolicy: Always
name: argocd-applicationset-controller
ports:
@@ -21765,7 +21765,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /shared/argocd-dex
image: quay.io/argoproj/argocd:latest
image: quay.io/argoproj/argocd:v2.11.0-rc3
imagePullPolicy: Always
name: copyutil
securityContext:
@@ -21847,7 +21847,7 @@ spec:
key: notificationscontroller.selfservice.enabled
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:latest
image: quay.io/argoproj/argocd:v2.11.0-rc3
imagePullPolicy: Always
livenessProbe:
tcpSocket:
@@ -22159,7 +22159,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:v2.11.0-rc3
imagePullPolicy: Always
livenessProbe:
failureThreshold: 3
@@ -22211,7 +22211,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /var/run/argocd/argocd-cmp-server
image: quay.io/argoproj/argocd:latest
image: quay.io/argoproj/argocd:v2.11.0-rc3
name: copyutil
securityContext:
allowPrivilegeEscalation: false
@@ -22528,7 +22528,7 @@ spec:
key: server.api.content.types
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:latest
image: quay.io/argoproj/argocd:v2.11.0-rc3
imagePullPolicy: Always
livenessProbe:
httpGet:
@@ -22816,7 +22816,13 @@ spec:
key: controller.diff.server.side
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:latest
- name: ARGOCD_IGNORE_NORMALIZER_JQ_TIMEOUT
valueFrom:
configMapKeyRef:
key: controller.ignore.normalizer.jq.timeout
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.11.0-rc3
imagePullPolicy: Always
name: argocd-application-controller
ports:

View File

@@ -763,7 +763,7 @@ spec:
key: applicationsetcontroller.enable.scm.providers
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:latest
image: quay.io/argoproj/argocd:v2.11.0-rc3
imagePullPolicy: Always
name: argocd-applicationset-controller
ports:
@@ -886,7 +886,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /shared/argocd-dex
image: quay.io/argoproj/argocd:latest
image: quay.io/argoproj/argocd:v2.11.0-rc3
imagePullPolicy: Always
name: copyutil
securityContext:
@@ -968,7 +968,7 @@ spec:
key: notificationscontroller.selfservice.enabled
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:latest
image: quay.io/argoproj/argocd:v2.11.0-rc3
imagePullPolicy: Always
livenessProbe:
tcpSocket:
@@ -1280,7 +1280,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:v2.11.0-rc3
imagePullPolicy: Always
livenessProbe:
failureThreshold: 3
@@ -1332,7 +1332,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /var/run/argocd/argocd-cmp-server
image: quay.io/argoproj/argocd:latest
image: quay.io/argoproj/argocd:v2.11.0-rc3
name: copyutil
securityContext:
allowPrivilegeEscalation: false
@@ -1649,7 +1649,7 @@ spec:
key: server.api.content.types
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:latest
image: quay.io/argoproj/argocd:v2.11.0-rc3
imagePullPolicy: Always
livenessProbe:
httpGet:
@@ -1937,7 +1937,13 @@ spec:
key: controller.diff.server.side
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:latest
- name: ARGOCD_IGNORE_NORMALIZER_JQ_TIMEOUT
valueFrom:
configMapKeyRef:
key: controller.ignore.normalizer.jq.timeout
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.11.0-rc3
imagePullPolicy: Always
name: argocd-application-controller
ports:

View File

@@ -372,14 +372,15 @@ func (m *ApplicationResourceEventsQuery) GetProject() string {
// ManifestQuery is a query for manifest resources
type ApplicationManifestQuery struct {
Name *string `protobuf:"bytes,1,req,name=name" json:"name,omitempty"`
Revision *string `protobuf:"bytes,2,opt,name=revision" json:"revision,omitempty"`
AppNamespace *string `protobuf:"bytes,3,opt,name=appNamespace" json:"appNamespace,omitempty"`
Project *string `protobuf:"bytes,4,opt,name=project" json:"project,omitempty"`
RevisionSourceMappings map[int64]string `protobuf:"bytes,5,rep,name=revisionSourceMappings" json:"revisionSourceMappings,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
Name *string `protobuf:"bytes,1,req,name=name" json:"name,omitempty"`
Revision *string `protobuf:"bytes,2,opt,name=revision" json:"revision,omitempty"`
AppNamespace *string `protobuf:"bytes,3,opt,name=appNamespace" json:"appNamespace,omitempty"`
Project *string `protobuf:"bytes,4,opt,name=project" json:"project,omitempty"`
SourcePositions []int64 `protobuf:"varint,5,rep,name=sourcePositions" json:"sourcePositions,omitempty"`
Revisions []string `protobuf:"bytes,6,rep,name=revisions" json:"revisions,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *ApplicationManifestQuery) Reset() { *m = ApplicationManifestQuery{} }
@@ -443,9 +444,16 @@ func (m *ApplicationManifestQuery) GetProject() string {
return ""
}
func (m *ApplicationManifestQuery) GetRevisionSourceMappings() map[int64]string {
func (m *ApplicationManifestQuery) GetSourcePositions() []int64 {
if m != nil {
return m.RevisionSourceMappings
return m.SourcePositions
}
return nil
}
func (m *ApplicationManifestQuery) GetRevisions() []string {
if m != nil {
return m.Revisions
}
return nil
}
@@ -965,6 +973,8 @@ type ApplicationSyncRequest struct {
SyncOptions *SyncOptions `protobuf:"bytes,11,opt,name=syncOptions" json:"syncOptions,omitempty"`
AppNamespace *string `protobuf:"bytes,12,opt,name=appNamespace" json:"appNamespace,omitempty"`
Project *string `protobuf:"bytes,13,opt,name=project" json:"project,omitempty"`
SourcePositions []int64 `protobuf:"varint,14,rep,name=sourcePositions" json:"sourcePositions,omitempty"`
Revisions []string `protobuf:"bytes,15,rep,name=revisions" json:"revisions,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@@ -1087,6 +1097,20 @@ func (m *ApplicationSyncRequest) GetProject() string {
return ""
}
func (m *ApplicationSyncRequest) GetSourcePositions() []int64 {
if m != nil {
return m.SourcePositions
}
return nil
}
func (m *ApplicationSyncRequest) GetRevisions() []string {
if m != nil {
return m.Revisions
}
return nil
}
// ApplicationUpdateSpecRequest is a request to update application spec
type ApplicationUpdateSpecRequest struct {
Name *string `protobuf:"bytes,1,req,name=name" json:"name,omitempty"`
@@ -2763,7 +2787,6 @@ func init() {
proto.RegisterType((*RevisionMetadataQuery)(nil), "application.RevisionMetadataQuery")
proto.RegisterType((*ApplicationResourceEventsQuery)(nil), "application.ApplicationResourceEventsQuery")
proto.RegisterType((*ApplicationManifestQuery)(nil), "application.ApplicationManifestQuery")
proto.RegisterMapType((map[int64]string)(nil), "application.ApplicationManifestQuery.RevisionSourceMappingsEntry")
proto.RegisterType((*FileChunk)(nil), "application.FileChunk")
proto.RegisterType((*ApplicationManifestQueryWithFiles)(nil), "application.ApplicationManifestQueryWithFiles")
proto.RegisterType((*ApplicationManifestQueryWithFilesWrapper)(nil), "application.ApplicationManifestQueryWithFilesWrapper")
@@ -2801,179 +2824,177 @@ func init() {
}
var fileDescriptor_df6e82b174b5eaec = []byte{
// 2738 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x5a, 0xcd, 0x8f, 0x1b, 0x49,
0x15, 0xa7, 0xec, 0xf9, 0xb0, 0x9f, 0x67, 0x92, 0x49, 0xed, 0x66, 0xe8, 0xed, 0x4c, 0xc2, 0xa4,
0xf3, 0x35, 0x99, 0x64, 0xec, 0xc4, 0x04, 0x94, 0x9d, 0xdd, 0x15, 0x24, 0x93, 0x4f, 0x98, 0xc9,
0x86, 0x9e, 0x84, 0xa0, 0xe5, 0x00, 0xb5, 0xed, 0x1a, 0x4f, 0x33, 0xed, 0xee, 0x4e, 0x77, 0xdb,
0x91, 0x15, 0x72, 0x59, 0x94, 0x0b, 0x5a, 0x81, 0x80, 0x3d, 0x20, 0x84, 0x00, 0x2d, 0x5a, 0x09,
0x21, 0x10, 0x17, 0xb4, 0x42, 0x42, 0x48, 0x70, 0x41, 0x70, 0x00, 0x21, 0x38, 0x72, 0x41, 0x11,
0xe2, 0x08, 0x97, 0xfd, 0x03, 0x50, 0x55, 0x57, 0xb5, 0xab, 0xfd, 0xd1, 0xf6, 0x60, 0xa3, 0xcd,
0xad, 0x5f, 0xb9, 0xea, 0xbd, 0xdf, 0x7b, 0xf5, 0xea, 0xbd, 0x57, 0xaf, 0x0c, 0x27, 0x43, 0x1a,
0xb4, 0x68, 0x50, 0x21, 0xbe, 0xef, 0xd8, 0x16, 0x89, 0x6c, 0xcf, 0x55, 0xbf, 0xcb, 0x7e, 0xe0,
0x45, 0x1e, 0x2e, 0x29, 0x43, 0xfa, 0x52, 0xdd, 0xf3, 0xea, 0x0e, 0xad, 0x10, 0xdf, 0xae, 0x10,
0xd7, 0xf5, 0x22, 0x3e, 0x1c, 0xc6, 0x53, 0x75, 0x63, 0xef, 0x72, 0x58, 0xb6, 0x3d, 0xfe, 0xab,
0xe5, 0x05, 0xb4, 0xd2, 0xba, 0x58, 0xa9, 0x53, 0x97, 0x06, 0x24, 0xa2, 0x35, 0x31, 0xe7, 0x52,
0x67, 0x4e, 0x83, 0x58, 0xbb, 0xb6, 0x4b, 0x83, 0x76, 0xc5, 0xdf, 0xab, 0xb3, 0x81, 0xb0, 0xd2,
0xa0, 0x11, 0xe9, 0xb7, 0x6a, 0xb3, 0x6e, 0x47, 0xbb, 0xcd, 0x37, 0xcb, 0x96, 0xd7, 0xa8, 0x90,
0xa0, 0xee, 0xf9, 0x81, 0xf7, 0x15, 0xfe, 0xb1, 0x66, 0xd5, 0x2a, 0xad, 0x6a, 0x87, 0x81, 0xaa,
0x4b, 0xeb, 0x22, 0x71, 0xfc, 0x5d, 0xd2, 0xcb, 0xed, 0xfa, 0x10, 0x6e, 0x01, 0xf5, 0x3d, 0x61,
0x1b, 0xfe, 0x69, 0x47, 0x5e, 0xd0, 0x56, 0x3e, 0x63, 0x36, 0xc6, 0x07, 0x08, 0x16, 0xae, 0x74,
0xe4, 0x7d, 0xae, 0x49, 0x83, 0x36, 0xc6, 0x30, 0xe5, 0x92, 0x06, 0xd5, 0xd0, 0x32, 0x5a, 0x29,
0x9a, 0xfc, 0x1b, 0x6b, 0x30, 0x1b, 0xd0, 0x9d, 0x80, 0x86, 0xbb, 0x5a, 0x8e, 0x0f, 0x4b, 0x12,
0xeb, 0x50, 0x60, 0xc2, 0xa9, 0x15, 0x85, 0x5a, 0x7e, 0x39, 0xbf, 0x52, 0x34, 0x13, 0x1a, 0xaf,
0xc0, 0xc1, 0x80, 0x86, 0x5e, 0x33, 0xb0, 0xe8, 0xe7, 0x69, 0x10, 0xda, 0x9e, 0xab, 0x4d, 0xf1,
0xd5, 0xdd, 0xc3, 0x8c, 0x4b, 0x48, 0x1d, 0x6a, 0x45, 0x5e, 0xa0, 0x4d, 0xf3, 0x29, 0x09, 0xcd,
0xf0, 0x30, 0xe0, 0xda, 0x4c, 0x8c, 0x87, 0x7d, 0x63, 0x03, 0xe6, 0x88, 0xef, 0xdf, 0x21, 0x0d,
0x1a, 0xfa, 0xc4, 0xa2, 0xda, 0x2c, 0xff, 0x2d, 0x35, 0xc6, 0x30, 0x0b, 0x24, 0x5a, 0x81, 0x03,
0x93, 0xa4, 0xb1, 0x01, 0xc5, 0x3b, 0x5e, 0x8d, 0x0e, 0x56, 0xb7, 0x9b, 0x7d, 0xae, 0x97, 0xbd,
0xf1, 0x14, 0xc1, 0x61, 0x93, 0xb6, 0x6c, 0x86, 0x7f, 0x8b, 0x46, 0xa4, 0x46, 0x22, 0xd2, 0xcd,
0x31, 0x97, 0x70, 0xd4, 0xa1, 0x10, 0x88, 0xc9, 0x5a, 0x8e, 0x8f, 0x27, 0x74, 0x8f, 0xb4, 0x7c,
0xb6, 0x32, 0xb1, 0x09, 0x13, 0x65, 0xfe, 0x85, 0xe0, 0x98, 0xb2, 0x87, 0xa6, 0xb0, 0xec, 0xf5,
0x16, 0x75, 0xa3, 0x70, 0x30, 0xa0, 0xf3, 0x70, 0x48, 0x6e, 0x42, 0xb7, 0x9e, 0xbd, 0x3f, 0x30,
0x88, 0xea, 0xa0, 0x84, 0xa8, 0x8e, 0xe1, 0x65, 0x28, 0x49, 0xfa, 0xfe, 0xed, 0x6b, 0x02, 0xa6,
0x3a, 0xd4, 0xa3, 0xe8, 0x74, 0xb6, 0xa2, 0x33, 0x69, 0x45, 0xff, 0x9c, 0x03, 0x4d, 0x51, 0x74,
0x8b, 0xb8, 0xf6, 0x0e, 0x0d, 0xa3, 0x51, 0x6d, 0x8e, 0x26, 0x67, 0x73, 0xdc, 0x86, 0x45, 0xc9,
0x69, 0x9b, 0x6b, 0xb7, 0x45, 0x7c, 0xdf, 0x76, 0xeb, 0xa1, 0x36, 0xbd, 0x9c, 0x5f, 0x29, 0x55,
0xaf, 0x94, 0xd5, 0x28, 0x34, 0x08, 0x74, 0xd9, 0xec, 0xcb, 0xe3, 0xba, 0x1b, 0x05, 0x6d, 0x73,
0x80, 0x00, 0xfd, 0x36, 0x1c, 0xc9, 0x58, 0x86, 0x17, 0x20, 0xbf, 0x47, 0xdb, 0xdc, 0x99, 0xf3,
0x26, 0xfb, 0xc4, 0x2f, 0xc2, 0x74, 0x8b, 0x38, 0x4d, 0xb9, 0xb9, 0x31, 0xb1, 0x9e, 0xbb, 0x8c,
0x8c, 0xe3, 0x50, 0xbc, 0x61, 0x3b, 0x74, 0x63, 0xb7, 0xe9, 0xee, 0xb1, 0x69, 0x16, 0xfb, 0xe0,
0x16, 0x9c, 0x33, 0x63, 0xc2, 0xf8, 0x16, 0x82, 0xe3, 0x83, 0xe0, 0x3f, 0xb0, 0xa3, 0x5d, 0xb6,
0x3e, 0x1c, 0x64, 0x7c, 0x6b, 0x97, 0x5a, 0x7b, 0x61, 0xb3, 0x21, 0x1d, 0x5e, 0xd2, 0x63, 0x3a,
0xfc, 0x4f, 0x11, 0xac, 0x0c, 0xc5, 0xf4, 0x20, 0x20, 0xbe, 0x4f, 0x03, 0x7c, 0x03, 0xa6, 0x1f,
0xb2, 0x1f, 0xb8, 0x45, 0x4a, 0xd5, 0xf2, 0x48, 0x1b, 0x93, 0x70, 0xb9, 0xf5, 0x11, 0x33, 0x5e,
0x8e, 0xcb, 0xd2, 0x3c, 0x39, 0xce, 0x67, 0x31, 0xc5, 0x27, 0xb1, 0x22, 0x9b, 0xcf, 0xa7, 0x5d,
0x9d, 0x81, 0x29, 0x9f, 0x04, 0x91, 0x71, 0x18, 0x5e, 0x48, 0x1f, 0x4e, 0xdf, 0x73, 0x43, 0x6a,
0xfc, 0x1a, 0xa5, 0x7c, 0x79, 0x23, 0xa0, 0x24, 0xa2, 0x26, 0x7d, 0xd8, 0xa4, 0x61, 0x84, 0xf7,
0x40, 0xcd, 0x58, 0xdc, 0xaa, 0xa5, 0xea, 0xed, 0x72, 0x27, 0xe4, 0x97, 0x65, 0xc8, 0xe7, 0x1f,
0x5f, 0xb2, 0x6a, 0xe5, 0x56, 0xb5, 0xec, 0xef, 0xd5, 0xcb, 0x2c, 0x81, 0xa4, 0x90, 0xc9, 0x04,
0xa2, 0xaa, 0x6a, 0xaa, 0xdc, 0xf1, 0x22, 0xcc, 0x34, 0xfd, 0x90, 0x06, 0x11, 0xd7, 0xac, 0x60,
0x0a, 0x8a, 0xed, 0x5f, 0x8b, 0x38, 0x76, 0x8d, 0x44, 0xf1, 0xfe, 0x14, 0xcc, 0x84, 0x36, 0x7e,
0x93, 0x46, 0x7f, 0xdf, 0xaf, 0x7d, 0x58, 0xe8, 0x55, 0x94, 0xb9, 0x34, 0x4a, 0xd5, 0x83, 0xf2,
0x69, 0x0f, 0xfa, 0x65, 0x1a, 0xff, 0x35, 0xea, 0xd0, 0x0e, 0xfe, 0x7e, 0xce, 0xac, 0xc1, 0xac,
0x45, 0x42, 0x8b, 0xd4, 0xa4, 0x14, 0x49, 0xb2, 0x30, 0xea, 0x07, 0x9e, 0x4f, 0xea, 0x9c, 0xd3,
0x5d, 0xcf, 0xb1, 0xad, 0xb6, 0x10, 0xd7, 0xfb, 0x43, 0x8f, 0xe3, 0x4f, 0x65, 0x3b, 0xfe, 0x74,
0x1a, 0xf6, 0x09, 0x28, 0x6d, 0xb7, 0x5d, 0xeb, 0x75, 0x9f, 0x57, 0x2c, 0xec, 0xc4, 0xda, 0x11,
0x6d, 0x84, 0x1a, 0xe2, 0xd9, 0x2d, 0x26, 0x8c, 0xf7, 0xa7, 0x61, 0x51, 0xd1, 0x8d, 0x2d, 0xc8,
0xd2, 0x2c, 0x2b, 0x46, 0x2e, 0xc2, 0x4c, 0x2d, 0x68, 0x9b, 0x4d, 0x57, 0x38, 0x80, 0xa0, 0x98,
0x60, 0x3f, 0x68, 0xba, 0x31, 0xfc, 0x82, 0x19, 0x13, 0x78, 0x07, 0x0a, 0x61, 0xc4, 0x6a, 0x94,
0x7a, 0x9b, 0x03, 0x2f, 0x55, 0x3f, 0x33, 0xde, 0xa6, 0x33, 0xe8, 0xdb, 0x82, 0xa3, 0x99, 0xf0,
0xc6, 0x0f, 0xa1, 0x28, 0x73, 0x4a, 0xa8, 0xcd, 0xf2, 0x70, 0xbb, 0x3d, 0xbe, 0xa0, 0xd7, 0x7d,
0x56, 0x5f, 0x29, 0xf9, 0xd3, 0xec, 0x48, 0xc1, 0x4b, 0x50, 0x6c, 0x88, 0xf8, 0x10, 0x8a, 0x5a,
0xa2, 0x33, 0x80, 0xbf, 0x00, 0xd3, 0xb6, 0xbb, 0xe3, 0x85, 0x5a, 0x91, 0x83, 0xb9, 0x3a, 0x1e,
0x98, 0xdb, 0xee, 0x8e, 0x67, 0xc6, 0x0c, 0xf1, 0x43, 0x98, 0x0f, 0x68, 0x14, 0xb4, 0xa5, 0x15,
0x34, 0xe0, 0x76, 0xfd, 0xec, 0x78, 0x12, 0x4c, 0x95, 0xa5, 0x99, 0x96, 0x80, 0xd7, 0xa1, 0x14,
0x76, 0x7c, 0x4c, 0x2b, 0x71, 0x81, 0x5a, 0x8a, 0x91, 0xe2, 0x83, 0xa6, 0x3a, 0xb9, 0xc7, 0xbb,
0xe7, 0xb2, 0xbd, 0x7b, 0x3e, 0xed, 0xdd, 0xff, 0x41, 0xb0, 0xd4, 0x13, 0x54, 0xb6, 0x7d, 0x9a,
0xe9, 0xbe, 0x04, 0xa6, 0x42, 0x9f, 0x5a, 0x3c, 0xc3, 0x94, 0xaa, 0x5b, 0x13, 0x8b, 0x32, 0x5c,
0x2e, 0x67, 0x9d, 0x15, 0x08, 0xc7, 0x3c, 0xcf, 0x3f, 0x44, 0xf0, 0x51, 0x45, 0xe6, 0x5d, 0x12,
0x59, 0xbb, 0x59, 0xca, 0xb2, 0x73, 0xc7, 0xe6, 0x88, 0x7c, 0x1a, 0x13, 0xcc, 0x39, 0xf9, 0xc7,
0xbd, 0xb6, 0xcf, 0x00, 0xb2, 0x5f, 0x3a, 0x03, 0x63, 0x96, 0x5c, 0x3f, 0x43, 0xa0, 0xab, 0xb1,
0xd7, 0x73, 0x9c, 0x37, 0x89, 0xb5, 0x97, 0x05, 0xf2, 0x00, 0xe4, 0xec, 0x1a, 0x47, 0x98, 0x37,
0x73, 0x76, 0x6d, 0x9f, 0x41, 0xa4, 0x1b, 0xee, 0x4c, 0x36, 0xdc, 0xd9, 0x34, 0xdc, 0x0f, 0xba,
0xe0, 0xca, 0xa3, 0x9c, 0x01, 0x77, 0x09, 0x8a, 0x6e, 0x57, 0xf9, 0xdb, 0x19, 0xe8, 0x53, 0xf6,
0xe6, 0x7a, 0xca, 0x5e, 0x0d, 0x66, 0x5b, 0xc9, 0xe5, 0x86, 0xfd, 0x2c, 0x49, 0xa6, 0x62, 0x3d,
0xf0, 0x9a, 0xbe, 0x30, 0x7a, 0x4c, 0x30, 0x14, 0x7b, 0xb6, 0x5b, 0xd3, 0x66, 0x62, 0x14, 0xec,
0x7b, 0xff, 0xd7, 0x99, 0x94, 0xda, 0x3f, 0xcf, 0xc1, 0xc7, 0xfa, 0xa8, 0x3d, 0xd4, 0x9f, 0x9e,
0x0f, 0xdd, 0x13, 0xaf, 0x9e, 0x1d, 0xe8, 0xd5, 0x85, 0x61, 0x5e, 0x5d, 0xcc, 0xb6, 0x17, 0xa4,
0xed, 0xf5, 0x93, 0x1c, 0x2c, 0xf7, 0xb1, 0xd7, 0xf0, 0x32, 0xe0, 0xb9, 0x31, 0xd8, 0x8e, 0x17,
0x08, 0x2f, 0x29, 0x98, 0x31, 0xc1, 0xce, 0x99, 0x17, 0xf8, 0xbb, 0xc4, 0xe5, 0xde, 0x51, 0x30,
0x05, 0x35, 0xa6, 0xa9, 0xbe, 0x9e, 0x03, 0x4d, 0xda, 0xe7, 0x8a, 0xc5, 0xad, 0xd5, 0x74, 0x9f,
0x7f, 0x13, 0x2d, 0xc2, 0x0c, 0xe1, 0x68, 0x85, 0x53, 0x09, 0xaa, 0xc7, 0x18, 0x85, 0x6c, 0x63,
0x14, 0xd3, 0xc6, 0x78, 0x8a, 0xd8, 0xdd, 0x4b, 0x35, 0x46, 0xb8, 0x69, 0x87, 0x91, 0x2c, 0xea,
0xf1, 0x0e, 0xcc, 0xc6, 0x72, 0xe2, 0x92, 0xac, 0x54, 0xdd, 0x1c, 0x37, 0x51, 0xa7, 0x0c, 0x2f,
0x99, 0x1b, 0x2f, 0xc3, 0x91, 0xbe, 0x51, 0x4e, 0xc0, 0xd0, 0xa1, 0x20, 0x8b, 0x13, 0xb1, 0x35,
0x09, 0x6d, 0x3c, 0x9d, 0x4a, 0xa7, 0x1c, 0xaf, 0xb6, 0xe9, 0xd5, 0x33, 0xba, 0x04, 0xd9, 0xdb,
0xc9, 0x4c, 0xe5, 0xd5, 0x94, 0x86, 0x80, 0x24, 0xd9, 0x3a, 0xcb, 0x73, 0x23, 0x62, 0xbb, 0x34,
0x10, 0x59, 0xb1, 0x33, 0xc0, 0xb6, 0x21, 0xb4, 0x5d, 0x8b, 0x6e, 0x53, 0xcb, 0x73, 0x6b, 0x21,
0xdf, 0xcf, 0xbc, 0x99, 0x1a, 0xc3, 0xb7, 0xa0, 0xc8, 0xe9, 0x7b, 0x76, 0x23, 0x4e, 0x03, 0xa5,
0xea, 0x6a, 0x39, 0xee, 0xbc, 0x95, 0xd5, 0xce, 0x5b, 0xc7, 0x86, 0x0d, 0x1a, 0x91, 0x72, 0xeb,
0x62, 0x99, 0xad, 0x30, 0x3b, 0x8b, 0x19, 0x96, 0x88, 0xd8, 0xce, 0xa6, 0xed, 0xf2, 0x82, 0x91,
0x89, 0xea, 0x0c, 0x30, 0x57, 0xd9, 0xf1, 0x1c, 0xc7, 0x7b, 0x24, 0xcf, 0x4d, 0x4c, 0xb1, 0x55,
0x4d, 0x37, 0xb2, 0x1d, 0x2e, 0x3f, 0x76, 0x84, 0xce, 0x00, 0x5f, 0x65, 0x3b, 0x11, 0x0d, 0xc4,
0x81, 0x11, 0x54, 0xe2, 0x8c, 0xa5, 0xb8, 0x99, 0x24, 0xcf, 0x6b, 0xec, 0xb6, 0x73, 0xaa, 0xdb,
0x76, 0x1f, 0x85, 0xf9, 0x3e, 0x1d, 0x15, 0xde, 0x5b, 0xa3, 0x2d, 0xdb, 0x6b, 0x86, 0xda, 0x81,
0xb8, 0xf4, 0x90, 0x74, 0x8f, 0x2b, 0x1f, 0xcc, 0x76, 0xe5, 0x85, 0xb4, 0x2b, 0xff, 0x16, 0x41,
0x61, 0xd3, 0xab, 0xc7, 0x3d, 0x03, 0x76, 0xbb, 0xf1, 0xdc, 0x88, 0xba, 0xd2, 0x5f, 0x24, 0xc9,
0x36, 0x21, 0xb2, 0x1b, 0x74, 0x3b, 0x22, 0x0d, 0x5f, 0xd4, 0x58, 0xfb, 0xda, 0x84, 0x64, 0x31,
0x33, 0x8c, 0x43, 0xc2, 0x88, 0x9f, 0xf8, 0x82, 0xc9, 0xbf, 0x99, 0x0a, 0xc9, 0x84, 0xed, 0x28,
0x10, 0xc7, 0x3d, 0x35, 0xa6, 0xba, 0xd8, 0x74, 0x8c, 0x4d, 0x90, 0x46, 0x03, 0x5e, 0x4a, 0x8a,
0xf6, 0x7b, 0x34, 0x68, 0xd8, 0x2e, 0xc9, 0x8e, 0xde, 0x23, 0x34, 0xf5, 0x32, 0xee, 0x8c, 0x5e,
0xea, 0xd0, 0xb1, 0x1a, 0xf8, 0x81, 0xed, 0xd6, 0xbc, 0x47, 0x19, 0x87, 0x67, 0x3c, 0x81, 0x7f,
0x4d, 0xf7, 0xf5, 0x14, 0x89, 0xc9, 0x49, 0xbf, 0x05, 0xf3, 0x2c, 0x26, 0xb4, 0xa8, 0xf8, 0x41,
0x84, 0x1d, 0x63, 0x50, 0x93, 0xa3, 0xc3, 0xc3, 0x4c, 0x2f, 0xc4, 0x9b, 0x70, 0x90, 0x84, 0xa1,
0x5d, 0x77, 0x69, 0x4d, 0xf2, 0xca, 0x8d, 0xcc, 0xab, 0x7b, 0x69, 0x7c, 0x5d, 0xe6, 0x33, 0xc4,
0x7e, 0x4b, 0xd2, 0xf8, 0x1a, 0x82, 0xc3, 0x7d, 0x99, 0x24, 0x27, 0x07, 0x29, 0x61, 0x5c, 0x87,
0x42, 0x68, 0xed, 0xd2, 0x5a, 0xd3, 0xa1, 0xb2, 0x87, 0x24, 0x69, 0xf6, 0x5b, 0xad, 0x19, 0xef,
0xbe, 0x48, 0x23, 0x09, 0x8d, 0x8f, 0x01, 0x34, 0x88, 0xdb, 0x24, 0x0e, 0x87, 0x30, 0xc5, 0x21,
0x28, 0x23, 0xc6, 0x12, 0xe8, 0xfd, 0x5c, 0x47, 0xf4, 0x66, 0xfe, 0x8d, 0xe0, 0x80, 0x0c, 0xaa,
0x62, 0x77, 0x57, 0xe0, 0xa0, 0x62, 0x86, 0x3b, 0x9d, 0x8d, 0xee, 0x1e, 0x1e, 0x12, 0x30, 0xa5,
0x97, 0xe4, 0xd3, 0xad, 0xf5, 0x56, 0xaa, 0x39, 0x3e, 0x72, 0xbe, 0x43, 0x13, 0xaa, 0x1f, 0xbf,
0x0a, 0xda, 0x16, 0x71, 0x49, 0x9d, 0xd6, 0x12, 0xb5, 0x13, 0x17, 0xfb, 0xb2, 0xda, 0x64, 0x18,
0xfb, 0x4a, 0x9f, 0x94, 0x5a, 0xf6, 0xce, 0x8e, 0x6c, 0x58, 0x04, 0x50, 0xd8, 0xb4, 0xdd, 0x3d,
0x76, 0xef, 0x65, 0x1a, 0x47, 0x76, 0xe4, 0x48, 0xeb, 0xc6, 0x04, 0x5e, 0x80, 0x7c, 0x33, 0x70,
0x84, 0x07, 0xb0, 0x4f, 0xbc, 0x0c, 0xa5, 0x1a, 0x0d, 0xad, 0xc0, 0xf6, 0xc5, 0xfe, 0xf3, 0x56,
0xb3, 0x32, 0xc4, 0xf6, 0xc1, 0xb6, 0x3c, 0x77, 0xc3, 0x21, 0x61, 0x28, 0x13, 0x50, 0x32, 0x60,
0xbc, 0x0a, 0xf3, 0x4c, 0x66, 0x47, 0xcd, 0x73, 0x69, 0x35, 0x0f, 0xa7, 0xe0, 0x4b, 0x78, 0x12,
0x31, 0x81, 0x17, 0x58, 0xde, 0xbf, 0xe2, 0xfb, 0x82, 0xc9, 0x88, 0xe5, 0x50, 0xbe, 0x5f, 0xfe,
0xec, 0xdb, 0xe3, 0xac, 0xfe, 0xfd, 0x04, 0x60, 0xf5, 0x9c, 0xd0, 0xa0, 0x65, 0x5b, 0x14, 0x7f,
0x1b, 0xc1, 0x14, 0x13, 0x8d, 0x8f, 0x0e, 0x3a, 0x96, 0xdc, 0x5f, 0xf5, 0xc9, 0x5d, 0x84, 0x99,
0x34, 0x63, 0xe9, 0xad, 0xbf, 0xfd, 0xf3, 0x3b, 0xb9, 0x45, 0xfc, 0x22, 0x7f, 0x17, 0x6b, 0x5d,
0x54, 0xdf, 0xa8, 0x42, 0xfc, 0x36, 0x02, 0x2c, 0xea, 0x20, 0xe5, 0xe5, 0x01, 0x9f, 0x1b, 0x04,
0xb1, 0xcf, 0x0b, 0x85, 0x7e, 0x54, 0xc9, 0x2a, 0x65, 0xcb, 0x0b, 0x28, 0xcb, 0x21, 0x7c, 0x02,
0x07, 0xb0, 0xca, 0x01, 0x9c, 0xc4, 0x46, 0x3f, 0x00, 0x95, 0xc7, 0xcc, 0xa2, 0x4f, 0x2a, 0x34,
0x96, 0xfb, 0x2e, 0x82, 0xe9, 0x07, 0xfc, 0x0e, 0x31, 0xc4, 0x48, 0xdb, 0x13, 0x33, 0x12, 0x17,
0xc7, 0xd1, 0x1a, 0x27, 0x38, 0xd2, 0xa3, 0xf8, 0x88, 0x44, 0x1a, 0x46, 0x01, 0x25, 0x8d, 0x14,
0xe0, 0x0b, 0x08, 0xbf, 0x87, 0x60, 0x26, 0x6e, 0xfa, 0xe2, 0x53, 0x83, 0x50, 0xa6, 0x9a, 0xc2,
0xfa, 0xe4, 0x3a, 0xa8, 0xc6, 0x59, 0x8e, 0xf1, 0x84, 0xd1, 0x77, 0x3b, 0xd7, 0x53, 0xfd, 0xd5,
0x77, 0x10, 0xe4, 0x6f, 0xd2, 0xa1, 0xfe, 0x36, 0x41, 0x70, 0x3d, 0x06, 0xec, 0xb3, 0xd5, 0xf8,
0xc7, 0x08, 0x5e, 0xba, 0x49, 0xa3, 0xfe, 0xe9, 0x11, 0xaf, 0x0c, 0xcf, 0x59, 0xc2, 0xed, 0xce,
0x8d, 0x30, 0x33, 0xc9, 0x0b, 0x15, 0x8e, 0xec, 0x2c, 0x3e, 0x93, 0xe5, 0x84, 0x61, 0xdb, 0xb5,
0x1e, 0x09, 0x1c, 0x7f, 0x44, 0xb0, 0xd0, 0xfd, 0x42, 0x88, 0xd3, 0x09, 0xb5, 0xef, 0x03, 0xa2,
0x7e, 0x67, 0xdc, 0x28, 0x9b, 0x66, 0x6a, 0x5c, 0xe1, 0xc8, 0x5f, 0xc1, 0x2f, 0x67, 0x21, 0x97,
0x6d, 0xdf, 0xb0, 0xf2, 0x58, 0x7e, 0x3e, 0xe1, 0xaf, 0xd9, 0x1c, 0xf6, 0x9f, 0x10, 0xbc, 0x28,
0xf9, 0x6e, 0xec, 0x92, 0x20, 0xba, 0x46, 0x59, 0x0d, 0x1d, 0x8e, 0xa4, 0xcf, 0x98, 0x59, 0x43,
0x95, 0x67, 0x5c, 0xe7, 0xba, 0x7c, 0x0a, 0xbf, 0xb6, 0x6f, 0x5d, 0x2c, 0xc6, 0xa6, 0x26, 0x60,
0xbf, 0x85, 0x60, 0xee, 0x26, 0x8d, 0xb6, 0x92, 0x2e, 0xee, 0xa9, 0x91, 0x5e, 0x86, 0xf4, 0xa5,
0xb2, 0xf2, 0x88, 0x2e, 0x7f, 0x4a, 0x5c, 0x64, 0x8d, 0x83, 0x3b, 0x83, 0x4f, 0x65, 0x81, 0xeb,
0x74, 0x8e, 0xdf, 0x45, 0x70, 0x58, 0x05, 0xd1, 0x79, 0x51, 0xfb, 0xc4, 0xfe, 0xde, 0xa9, 0xc4,
0x6b, 0xd7, 0x10, 0x74, 0x55, 0x8e, 0xee, 0xbc, 0xd1, 0xdf, 0x81, 0x1b, 0x3d, 0x28, 0xd6, 0xd1,
0xea, 0x0a, 0xc2, 0xbf, 0x43, 0x30, 0x13, 0x37, 0x63, 0x07, 0xdb, 0x28, 0xf5, 0x02, 0x34, 0xc9,
0x68, 0x20, 0x76, 0x5b, 0xbf, 0xd0, 0xdf, 0xa0, 0xea, 0x7a, 0xe9, 0xaa, 0x65, 0x6e, 0xe5, 0x74,
0x18, 0x7b, 0x1f, 0x01, 0x74, 0x1a, 0xca, 0xf8, 0x6c, 0xb6, 0x1e, 0x4a, 0xd3, 0x59, 0x9f, 0x6c,
0x4b, 0xd9, 0x28, 0x73, 0x7d, 0x56, 0xf4, 0xe5, 0xcc, 0x18, 0xe2, 0x53, 0x6b, 0x3d, 0x6e, 0x3e,
0xff, 0x08, 0xc1, 0x34, 0xef, 0xe3, 0xe1, 0x93, 0x83, 0x30, 0xab, 0x6d, 0xbe, 0x49, 0x9a, 0xfe,
0x34, 0x87, 0xba, 0x5c, 0xcd, 0x0a, 0xc4, 0xeb, 0x68, 0x15, 0xb7, 0x60, 0x26, 0xee, 0x9c, 0x0d,
0x76, 0x8f, 0x54, 0x67, 0x4d, 0x5f, 0xce, 0x28, 0x0c, 0x62, 0x47, 0x15, 0x39, 0x60, 0x75, 0x58,
0x0e, 0x98, 0x62, 0x61, 0x1a, 0x9f, 0xc8, 0x0a, 0xe2, 0xff, 0x07, 0xc3, 0x9c, 0xe3, 0xe8, 0x4e,
0x19, 0xcb, 0xc3, 0xf2, 0x00, 0xb3, 0xce, 0x77, 0x11, 0x2c, 0x74, 0x17, 0xd7, 0xf8, 0x48, 0x57,
0xcc, 0x54, 0xef, 0x1a, 0x7a, 0xda, 0x8a, 0x83, 0x0a, 0x73, 0xe3, 0xd3, 0x1c, 0xc5, 0x3a, 0xbe,
0x3c, 0xf4, 0x64, 0xdc, 0x91, 0x51, 0x87, 0x31, 0x5a, 0xeb, 0xbc, 0x6a, 0xfd, 0x0a, 0xc1, 0x9c,
0xe4, 0x7b, 0x2f, 0xa0, 0x34, 0x1b, 0xd6, 0xe4, 0x0e, 0x02, 0x93, 0x65, 0xbc, 0xca, 0xe1, 0x7f,
0x12, 0x5f, 0x1a, 0x11, 0xbe, 0x84, 0xbd, 0x16, 0x31, 0xa4, 0xbf, 0x47, 0x70, 0xe8, 0x41, 0xec,
0xf7, 0x1f, 0x12, 0xfe, 0x0d, 0x8e, 0xff, 0x35, 0xfc, 0x4a, 0x46, 0x9d, 0x37, 0x4c, 0x8d, 0x0b,
0x08, 0xff, 0x02, 0x41, 0x41, 0xbe, 0xaa, 0xe0, 0x33, 0x03, 0x0f, 0x46, 0xfa, 0xdd, 0x65, 0x92,
0xce, 0x2c, 0x8a, 0x1a, 0xe3, 0x64, 0x66, 0x3a, 0x15, 0xf2, 0x99, 0x43, 0xbf, 0x83, 0x00, 0x27,
0x77, 0xe6, 0xe4, 0x16, 0x8d, 0x4f, 0xa7, 0x44, 0x0d, 0x6c, 0xcc, 0xe8, 0x67, 0x86, 0xce, 0x4b,
0xa7, 0xd2, 0xd5, 0xcc, 0x54, 0xea, 0x25, 0xf2, 0xbf, 0x81, 0xa0, 0x74, 0x93, 0x26, 0x77, 0x90,
0x0c, 0x5b, 0xa6, 0x1f, 0x85, 0xf4, 0x95, 0xe1, 0x13, 0x05, 0xa2, 0xf3, 0x1c, 0xd1, 0x69, 0x9c,
0x6d, 0x2a, 0x09, 0xe0, 0xfb, 0x08, 0xe6, 0xef, 0xaa, 0x2e, 0x8a, 0xcf, 0x0f, 0x93, 0x94, 0x8a,
0xe4, 0xa3, 0xe3, 0xfa, 0x38, 0xc7, 0xb5, 0x66, 0x8c, 0x84, 0x6b, 0x5d, 0xbc, 0xaf, 0xfc, 0x00,
0xc5, 0x97, 0xd8, 0xae, 0x7e, 0xf6, 0xff, 0x6a, 0xb7, 0x8c, 0xb6, 0xb8, 0x71, 0x89, 0xe3, 0x2b,
0xe3, 0xf3, 0xa3, 0xe0, 0xab, 0x88, 0x26, 0x37, 0xfe, 0x1e, 0x82, 0x43, 0xfc, 0xad, 0x41, 0x65,
0xdc, 0x95, 0x62, 0x06, 0xbd, 0x4c, 0x8c, 0x90, 0x62, 0x44, 0xfc, 0x31, 0xf6, 0x05, 0x6a, 0x5d,
0xbe, 0x23, 0x7c, 0x13, 0xc1, 0x01, 0x99, 0xd4, 0xc4, 0xee, 0xae, 0x0d, 0x33, 0xdc, 0x7e, 0x93,
0xa0, 0x70, 0xb7, 0xd5, 0xd1, 0xdc, 0xed, 0x3d, 0x04, 0xb3, 0xa2, 0x9b, 0x9f, 0x51, 0x2a, 0x28,
0xed, 0x7e, 0xbd, 0xab, 0xc7, 0x21, 0x9a, 0xc1, 0xc6, 0x17, 0xb9, 0xd8, 0xfb, 0xb8, 0x92, 0x25,
0xd6, 0xf7, 0x6a, 0x61, 0xe5, 0xb1, 0xe8, 0xc4, 0x3e, 0xa9, 0x38, 0x5e, 0x3d, 0x7c, 0xc3, 0xc0,
0x99, 0x09, 0x91, 0xcd, 0xb9, 0x80, 0x70, 0x04, 0x45, 0xe6, 0x1c, 0xbc, 0x71, 0x82, 0x97, 0xbb,
0xda, 0x2c, 0x3d, 0x3d, 0x15, 0x5d, 0xef, 0x69, 0xc4, 0x74, 0x32, 0xa0, 0xb8, 0xc6, 0xe2, 0xe3,
0x99, 0x62, 0xb9, 0xa0, 0xb7, 0x11, 0x1c, 0x52, 0xbd, 0x3d, 0x16, 0x3f, 0xb2, 0xaf, 0x67, 0xa1,
0x10, 0x45, 0x35, 0x5e, 0x1d, 0xc9, 0x91, 0x38, 0x9c, 0xab, 0x37, 0xfe, 0xf0, 0xec, 0x18, 0xfa,
0xcb, 0xb3, 0x63, 0xe8, 0x1f, 0xcf, 0x8e, 0xa1, 0x37, 0x2e, 0x8f, 0xf6, 0xcf, 0x60, 0xcb, 0xb1,
0xa9, 0x1b, 0xa9, 0xec, 0xff, 0x1b, 0x00, 0x00, 0xff, 0xff, 0x5e, 0x21, 0x6e, 0x60, 0xff, 0x2c,
0x00, 0x00,
// 2711 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x5a, 0x4d, 0x8c, 0x1b, 0x49,
0x15, 0xa6, 0xec, 0xb1, 0xc7, 0xf3, 0x3c, 0x93, 0x9f, 0xda, 0x64, 0xe8, 0x75, 0x66, 0x83, 0xd3,
0xf9, 0x9b, 0x4c, 0x32, 0x76, 0x62, 0x02, 0xca, 0xce, 0xee, 0x0a, 0x92, 0xc9, 0x2f, 0x4c, 0xb2,
0xa1, 0x27, 0x21, 0x68, 0x39, 0x40, 0x6d, 0xbb, 0xc6, 0xd3, 0x4c, 0xbb, 0xbb, 0xd3, 0xdd, 0x76,
0x34, 0x0a, 0xb9, 0x2c, 0xca, 0x05, 0xad, 0x40, 0xc0, 0x1e, 0x10, 0x42, 0x80, 0x16, 0xad, 0x84,
0x10, 0x88, 0x0b, 0x42, 0x48, 0x08, 0x09, 0x2e, 0x08, 0x0e, 0x48, 0x2b, 0x38, 0x72, 0x41, 0x11,
0xe2, 0x08, 0x97, 0x3d, 0x23, 0x54, 0xd5, 0x55, 0xdd, 0xd5, 0xfe, 0x69, 0x7b, 0xb0, 0xd1, 0xe6,
0xd6, 0xaf, 0x5c, 0xf5, 0xde, 0xf7, 0x5e, 0xbd, 0x7a, 0xef, 0xd5, 0x2b, 0xc3, 0x89, 0x80, 0xfa,
0x5d, 0xea, 0xd7, 0x89, 0xe7, 0xd9, 0x96, 0x49, 0x42, 0xcb, 0x75, 0xd4, 0xef, 0x9a, 0xe7, 0xbb,
0xa1, 0x8b, 0xcb, 0xca, 0x50, 0x65, 0xa9, 0xe5, 0xba, 0x2d, 0x9b, 0xd6, 0x89, 0x67, 0xd5, 0x89,
0xe3, 0xb8, 0x21, 0x1f, 0x0e, 0xa2, 0xa9, 0x15, 0x7d, 0xe7, 0x52, 0x50, 0xb3, 0x5c, 0xfe, 0xab,
0xe9, 0xfa, 0xb4, 0xde, 0xbd, 0x50, 0x6f, 0x51, 0x87, 0xfa, 0x24, 0xa4, 0x4d, 0x31, 0xe7, 0x62,
0x32, 0xa7, 0x4d, 0xcc, 0x6d, 0xcb, 0xa1, 0xfe, 0x6e, 0xdd, 0xdb, 0x69, 0xb1, 0x81, 0xa0, 0xde,
0xa6, 0x21, 0x19, 0xb4, 0x6a, 0xa3, 0x65, 0x85, 0xdb, 0x9d, 0x37, 0x6b, 0xa6, 0xdb, 0xae, 0x13,
0xbf, 0xe5, 0x7a, 0xbe, 0xfb, 0x15, 0xfe, 0xb1, 0x6a, 0x36, 0xeb, 0xdd, 0x46, 0xc2, 0x40, 0xd5,
0xa5, 0x7b, 0x81, 0xd8, 0xde, 0x36, 0xe9, 0xe7, 0x76, 0x6d, 0x04, 0x37, 0x9f, 0x7a, 0xae, 0xb0,
0x0d, 0xff, 0xb4, 0x42, 0xd7, 0xdf, 0x55, 0x3e, 0x23, 0x36, 0xfa, 0x07, 0x08, 0x0e, 0x5c, 0x4e,
0xe4, 0x7d, 0xae, 0x43, 0xfd, 0x5d, 0x8c, 0x61, 0xc6, 0x21, 0x6d, 0xaa, 0xa1, 0x2a, 0x5a, 0x9e,
0x33, 0xf8, 0x37, 0xd6, 0x60, 0xd6, 0xa7, 0x5b, 0x3e, 0x0d, 0xb6, 0xb5, 0x1c, 0x1f, 0x96, 0x24,
0xae, 0x40, 0x89, 0x09, 0xa7, 0x66, 0x18, 0x68, 0xf9, 0x6a, 0x7e, 0x79, 0xce, 0x88, 0x69, 0xbc,
0x0c, 0xfb, 0x7d, 0x1a, 0xb8, 0x1d, 0xdf, 0xa4, 0x9f, 0xa7, 0x7e, 0x60, 0xb9, 0x8e, 0x36, 0xc3,
0x57, 0xf7, 0x0e, 0x33, 0x2e, 0x01, 0xb5, 0xa9, 0x19, 0xba, 0xbe, 0x56, 0xe0, 0x53, 0x62, 0x9a,
0xe1, 0x61, 0xc0, 0xb5, 0x62, 0x84, 0x87, 0x7d, 0x63, 0x1d, 0xe6, 0x89, 0xe7, 0xdd, 0x21, 0x6d,
0x1a, 0x78, 0xc4, 0xa4, 0xda, 0x2c, 0xff, 0x2d, 0x35, 0xc6, 0x30, 0x0b, 0x24, 0x5a, 0x89, 0x03,
0x93, 0xa4, 0xbe, 0x0e, 0x73, 0x77, 0xdc, 0x26, 0x1d, 0xae, 0x6e, 0x2f, 0xfb, 0x5c, 0x3f, 0x7b,
0xfd, 0x29, 0x82, 0xc3, 0x06, 0xed, 0x5a, 0x0c, 0xff, 0x6d, 0x1a, 0x92, 0x26, 0x09, 0x49, 0x2f,
0xc7, 0x5c, 0xcc, 0xb1, 0x02, 0x25, 0x5f, 0x4c, 0xd6, 0x72, 0x7c, 0x3c, 0xa6, 0xfb, 0xa4, 0xe5,
0xb3, 0x95, 0x89, 0x4c, 0x18, 0x2b, 0xf3, 0x4f, 0x04, 0x47, 0x95, 0x3d, 0x34, 0x84, 0x65, 0xaf,
0x75, 0xa9, 0x13, 0x06, 0xc3, 0x01, 0x9d, 0x83, 0x83, 0x72, 0x13, 0x7a, 0xf5, 0xec, 0xff, 0x81,
0x41, 0x54, 0x07, 0x25, 0x44, 0x75, 0x0c, 0x57, 0xa1, 0x2c, 0xe9, 0xfb, 0xb7, 0xae, 0x0a, 0x98,
0xea, 0x50, 0x9f, 0xa2, 0x85, 0x6c, 0x45, 0x8b, 0x69, 0x45, 0xdf, 0x47, 0xa0, 0x29, 0x8a, 0xde,
0x26, 0x8e, 0xb5, 0x45, 0x83, 0x70, 0x5c, 0x9b, 0xa3, 0xe9, 0xd9, 0x9c, 0x39, 0x76, 0xa4, 0xd5,
0x5d, 0x76, 0x9e, 0x58, 0xfc, 0xd0, 0x0a, 0xd5, 0xfc, 0x72, 0xde, 0xe8, 0x1d, 0xc6, 0x4b, 0x30,
0x27, 0x65, 0x06, 0x5a, 0x91, 0xbb, 0x61, 0x32, 0xa0, 0x1f, 0x83, 0xb9, 0xeb, 0x96, 0x4d, 0xd7,
0xb7, 0x3b, 0xce, 0x0e, 0x3e, 0x04, 0x05, 0x93, 0x7d, 0x70, 0x1d, 0xe6, 0x8d, 0x88, 0xd0, 0xbf,
0x85, 0xe0, 0xd8, 0x30, 0xad, 0x1f, 0x58, 0xe1, 0x36, 0x5b, 0x1f, 0x0c, 0x53, 0xdf, 0xdc, 0xa6,
0xe6, 0x4e, 0xd0, 0x69, 0x4b, 0x97, 0x93, 0xf4, 0x84, 0x2e, 0xf7, 0x53, 0x04, 0xcb, 0x23, 0x31,
0x3d, 0xf0, 0x89, 0xe7, 0x51, 0x1f, 0x5f, 0x87, 0xc2, 0x43, 0xf6, 0x03, 0x3f, 0x60, 0xe5, 0x46,
0xad, 0xa6, 0x06, 0xe8, 0x91, 0x5c, 0x6e, 0x7e, 0xc4, 0x88, 0x96, 0xe3, 0x9a, 0x34, 0x4f, 0x8e,
0xf3, 0x59, 0x4c, 0xf1, 0x89, 0xad, 0xc8, 0xe6, 0xf3, 0x69, 0x57, 0x8a, 0x30, 0xe3, 0x11, 0x3f,
0xd4, 0x0f, 0xc3, 0x0b, 0xe9, 0xe3, 0xe1, 0xb9, 0x4e, 0x40, 0xf5, 0xdf, 0xa4, 0xbd, 0x69, 0xdd,
0xa7, 0x24, 0xa4, 0x06, 0x7d, 0xd8, 0xa1, 0x41, 0x88, 0x77, 0x40, 0xcd, 0x19, 0xdc, 0xaa, 0xe5,
0xc6, 0xad, 0x5a, 0x12, 0x74, 0x6b, 0x32, 0xe8, 0xf2, 0x8f, 0x2f, 0x99, 0xcd, 0x5a, 0xb7, 0x51,
0xf3, 0x76, 0x5a, 0x35, 0x16, 0xc2, 0x53, 0xc8, 0x64, 0x08, 0x57, 0x55, 0x35, 0x54, 0xee, 0x78,
0x11, 0x8a, 0x1d, 0x2f, 0xa0, 0x7e, 0xc8, 0x35, 0x2b, 0x19, 0x82, 0x62, 0xfb, 0xd7, 0x25, 0xb6,
0xd5, 0x24, 0x61, 0xb4, 0x3f, 0x25, 0x23, 0xa6, 0xf5, 0xdf, 0xa6, 0xd1, 0xdf, 0xf7, 0x9a, 0x1f,
0x16, 0x7a, 0x15, 0x65, 0x2e, 0x8d, 0x52, 0xf5, 0xa0, 0x7c, 0xda, 0x83, 0x7e, 0x99, 0xc6, 0x7f,
0x95, 0xda, 0x34, 0xc1, 0x3f, 0xc8, 0x99, 0x35, 0x98, 0x35, 0x49, 0x60, 0x92, 0xa6, 0x94, 0x22,
0x49, 0x16, 0xc8, 0x3c, 0xdf, 0xf5, 0x48, 0x8b, 0x73, 0xba, 0xeb, 0xda, 0x96, 0xb9, 0x2b, 0xc4,
0xf5, 0xff, 0xd0, 0xe7, 0xf8, 0x33, 0xd9, 0x8e, 0x5f, 0x48, 0xc3, 0x3e, 0x0e, 0xe5, 0xcd, 0x5d,
0xc7, 0x7c, 0xdd, 0x8b, 0x0e, 0xf7, 0x21, 0x28, 0x58, 0x21, 0x6d, 0x07, 0x1a, 0xe2, 0x07, 0x3b,
0x22, 0xf4, 0xff, 0x14, 0x60, 0x51, 0xd1, 0x8d, 0x2d, 0xc8, 0xd2, 0x2c, 0x2b, 0x4a, 0x2d, 0x42,
0xb1, 0xe9, 0xef, 0x1a, 0x1d, 0x47, 0x38, 0x80, 0xa0, 0x98, 0x60, 0xcf, 0xef, 0x38, 0x11, 0xfc,
0x92, 0x11, 0x11, 0x78, 0x0b, 0x4a, 0x41, 0xc8, 0xaa, 0x84, 0xd6, 0x2e, 0x07, 0x5e, 0x6e, 0x7c,
0x66, 0xb2, 0x4d, 0x67, 0xd0, 0x37, 0x05, 0x47, 0x23, 0xe6, 0x8d, 0x1f, 0xb2, 0x98, 0x16, 0x05,
0xba, 0x40, 0x9b, 0xad, 0xe6, 0x97, 0xcb, 0x8d, 0xcd, 0xc9, 0x05, 0xbd, 0xee, 0xb1, 0x0a, 0x47,
0xc9, 0x60, 0x46, 0x22, 0x85, 0x85, 0xd1, 0xb6, 0x88, 0x0f, 0x81, 0xc8, 0xe6, 0xc9, 0x00, 0xfe,
0x02, 0x14, 0x2c, 0x67, 0xcb, 0x0d, 0xb4, 0x39, 0x0e, 0xe6, 0xca, 0x64, 0x60, 0x6e, 0x39, 0x5b,
0xae, 0x11, 0x31, 0xc4, 0x0f, 0x61, 0xc1, 0xa7, 0xa1, 0xbf, 0x2b, 0xad, 0xa0, 0x01, 0xb7, 0xeb,
0x67, 0x27, 0x93, 0x60, 0xa8, 0x2c, 0x8d, 0xb4, 0x04, 0xbc, 0x06, 0xe5, 0x20, 0xf1, 0x31, 0xad,
0xcc, 0x05, 0x6a, 0x29, 0x46, 0x8a, 0x0f, 0x1a, 0xea, 0xe4, 0x3e, 0xef, 0x9e, 0xcf, 0xf6, 0xee,
0x85, 0x91, 0x59, 0x6d, 0xdf, 0x18, 0x59, 0x6d, 0x7f, 0x6f, 0x56, 0xfb, 0x37, 0x82, 0xa5, 0xbe,
0xe0, 0xb4, 0xe9, 0xd1, 0xcc, 0x63, 0x40, 0x60, 0x26, 0xf0, 0xa8, 0xc9, 0x33, 0x55, 0xb9, 0x71,
0x7b, 0x6a, 0xd1, 0x8a, 0xcb, 0xe5, 0xac, 0xb3, 0x02, 0xea, 0x84, 0x71, 0xe1, 0x87, 0x08, 0x3e,
0xaa, 0xc8, 0xbc, 0x4b, 0x42, 0x73, 0x3b, 0x4b, 0x59, 0x76, 0x7e, 0xd9, 0x1c, 0x91, 0x97, 0x23,
0x82, 0x59, 0x95, 0x7f, 0xdc, 0xdb, 0xf5, 0x18, 0x40, 0xf6, 0x4b, 0x32, 0x30, 0x61, 0xf1, 0xf4,
0x33, 0x04, 0x15, 0x35, 0x86, 0xbb, 0xb6, 0xfd, 0x26, 0x31, 0x77, 0xb2, 0x40, 0xee, 0x83, 0x9c,
0xd5, 0xe4, 0x08, 0xf3, 0x46, 0xce, 0x6a, 0xee, 0x31, 0x18, 0xf5, 0xc2, 0x2d, 0x66, 0xc3, 0x9d,
0x4d, 0xc3, 0xfd, 0xa0, 0x07, 0xae, 0x0c, 0x09, 0x19, 0x70, 0x97, 0x60, 0xce, 0xe9, 0x29, 0x64,
0x93, 0x81, 0x01, 0x05, 0x6c, 0xae, 0xaf, 0x80, 0xd5, 0x60, 0xb6, 0x1b, 0x5f, 0x53, 0xd8, 0xcf,
0x92, 0x64, 0x2a, 0xb6, 0x7c, 0xb7, 0xe3, 0x09, 0xa3, 0x47, 0x04, 0x43, 0xb1, 0x63, 0x39, 0x4d,
0xad, 0x18, 0xa1, 0x60, 0xdf, 0x7b, 0xbf, 0x98, 0xa4, 0xd4, 0xfe, 0x79, 0x0e, 0x3e, 0x36, 0x40,
0xed, 0x91, 0xfe, 0xf4, 0x7c, 0xe8, 0x1e, 0x7b, 0xf5, 0xec, 0x50, 0xaf, 0x2e, 0x8d, 0xf2, 0xea,
0xb9, 0x6c, 0x7b, 0x41, 0xda, 0x5e, 0x3f, 0xc9, 0x41, 0x75, 0x80, 0xbd, 0x46, 0x97, 0x13, 0xcf,
0x8d, 0xc1, 0xb6, 0x5c, 0x5f, 0x78, 0x49, 0xc9, 0x88, 0x08, 0x76, 0xce, 0x5c, 0xdf, 0xdb, 0x26,
0x0e, 0xf7, 0x8e, 0x92, 0x21, 0xa8, 0x09, 0x4d, 0xf5, 0xf5, 0x1c, 0x68, 0xd2, 0x3e, 0x97, 0x4d,
0x6e, 0xad, 0x8e, 0xf3, 0xfc, 0x9b, 0x68, 0x11, 0x8a, 0x84, 0xa3, 0x15, 0x4e, 0x25, 0xa8, 0x3e,
0x63, 0x94, 0xb2, 0x8d, 0x31, 0x97, 0x36, 0xc6, 0x53, 0x04, 0x47, 0xd2, 0xc6, 0x08, 0x36, 0xac,
0x20, 0x94, 0x97, 0x03, 0xbc, 0x05, 0xb3, 0x91, 0x9c, 0xa8, 0xb4, 0x2b, 0x37, 0x36, 0x26, 0x4d,
0xf8, 0x29, 0xc3, 0x4b, 0xe6, 0xfa, 0xcb, 0x70, 0x64, 0x60, 0x94, 0x13, 0x30, 0x2a, 0x50, 0x92,
0x45, 0x8e, 0xd8, 0x9a, 0x98, 0xd6, 0x9f, 0xce, 0xa4, 0x53, 0x8e, 0xdb, 0xdc, 0x70, 0x5b, 0x19,
0xf7, 0xfd, 0xec, 0xed, 0x64, 0xa6, 0x72, 0x9b, 0xca, 0xd5, 0x5e, 0x92, 0x6c, 0x9d, 0xe9, 0x3a,
0x21, 0xb1, 0x1c, 0xea, 0x8b, 0xac, 0x98, 0x0c, 0xb0, 0x6d, 0x08, 0x2c, 0xc7, 0xa4, 0x9b, 0xd4,
0x74, 0x9d, 0x66, 0xc0, 0xf7, 0x33, 0x6f, 0xa4, 0xc6, 0xf0, 0x4d, 0x98, 0xe3, 0xf4, 0x3d, 0xab,
0x1d, 0xa5, 0x81, 0x72, 0x63, 0xa5, 0x16, 0xf5, 0xd0, 0x6a, 0x6a, 0x0f, 0x2d, 0xb1, 0x61, 0x9b,
0x86, 0xa4, 0xd6, 0xbd, 0x50, 0x63, 0x2b, 0x8c, 0x64, 0x31, 0xc3, 0x12, 0x12, 0xcb, 0xde, 0xb0,
0x1c, 0x5e, 0x78, 0x32, 0x51, 0xc9, 0x00, 0x73, 0x95, 0x2d, 0xd7, 0xb6, 0xdd, 0x47, 0xf2, 0xdc,
0x44, 0x14, 0x5b, 0xd5, 0x71, 0x42, 0xcb, 0xe6, 0xf2, 0x23, 0x47, 0x48, 0x06, 0xf8, 0x2a, 0xcb,
0x0e, 0xa9, 0x2f, 0x0e, 0x8c, 0xa0, 0x62, 0x67, 0x2c, 0x47, 0x6d, 0x21, 0x79, 0x5e, 0x23, 0xb7,
0x9d, 0x57, 0xdd, 0xb6, 0xf7, 0x28, 0x2c, 0x0c, 0xe8, 0x8d, 0xf0, 0x2e, 0x19, 0xed, 0x5a, 0x6e,
0x87, 0xd5, 0x54, 0xbc, 0xf4, 0x90, 0x74, 0x9f, 0x2b, 0xef, 0xcf, 0x76, 0xe5, 0x03, 0x69, 0x57,
0xfe, 0x1d, 0x82, 0xd2, 0x86, 0xdb, 0xba, 0xe6, 0x84, 0xfe, 0x2e, 0xbf, 0x25, 0xb9, 0x4e, 0x48,
0x1d, 0xe9, 0x2f, 0x92, 0x64, 0x9b, 0x10, 0x5a, 0x6d, 0xba, 0x19, 0x92, 0xb6, 0x27, 0x6a, 0xac,
0x3d, 0x6d, 0x42, 0xbc, 0x98, 0x19, 0xc6, 0x26, 0x41, 0xc8, 0x4f, 0x7c, 0xc9, 0xe0, 0xdf, 0x4c,
0x85, 0x78, 0xc2, 0x66, 0xe8, 0x8b, 0xe3, 0x9e, 0x1a, 0x53, 0x5d, 0xac, 0x10, 0x61, 0x13, 0xa4,
0xde, 0x86, 0x17, 0xe3, 0xe2, 0xff, 0x1e, 0xf5, 0xdb, 0x96, 0x43, 0xb2, 0xa3, 0xf7, 0x18, 0xed,
0xb9, 0x8c, 0xbb, 0xa7, 0x9b, 0x3a, 0x74, 0xac, 0x96, 0x7e, 0x60, 0x39, 0x4d, 0xf7, 0x51, 0xc6,
0xe1, 0x99, 0x4c, 0xe0, 0x5f, 0xd2, 0x1d, 0x3a, 0x45, 0x62, 0x7c, 0xd2, 0x6f, 0xc2, 0x02, 0x8b,
0x09, 0x5d, 0x2a, 0x7e, 0x10, 0x61, 0x47, 0x1f, 0xd6, 0x2c, 0x49, 0x78, 0x18, 0xe9, 0x85, 0x78,
0x03, 0xf6, 0x93, 0x20, 0xb0, 0x5a, 0x0e, 0x6d, 0x4a, 0x5e, 0xb9, 0xb1, 0x79, 0xf5, 0x2e, 0x8d,
0xae, 0xdd, 0x7c, 0x86, 0xd8, 0x6f, 0x49, 0xea, 0x5f, 0x43, 0x70, 0x78, 0x20, 0x93, 0xf8, 0xe4,
0x20, 0x25, 0x8c, 0x57, 0xa0, 0x14, 0x98, 0xdb, 0xb4, 0xd9, 0xb1, 0xa9, 0xec, 0x45, 0x49, 0x9a,
0xfd, 0xd6, 0xec, 0x44, 0xbb, 0x2f, 0xd2, 0x48, 0x4c, 0xe3, 0xa3, 0x00, 0x6d, 0xe2, 0x74, 0x88,
0xcd, 0x21, 0xcc, 0x70, 0x08, 0xca, 0x88, 0xbe, 0x04, 0x95, 0x41, 0xae, 0x23, 0x7a, 0x3c, 0xff,
0x42, 0xb0, 0x4f, 0x06, 0x55, 0xb1, 0xbb, 0xcb, 0xb0, 0x5f, 0x31, 0xc3, 0x9d, 0x64, 0xa3, 0x7b,
0x87, 0x47, 0x04, 0x4c, 0xe9, 0x25, 0xf9, 0x74, 0x93, 0xbc, 0x9b, 0x6a, 0x73, 0x8f, 0x9d, 0xef,
0xd0, 0x94, 0xea, 0xc7, 0xaf, 0x82, 0x76, 0x9b, 0x38, 0xa4, 0x45, 0x9b, 0xb1, 0xda, 0xb1, 0x8b,
0x7d, 0x59, 0x6d, 0x56, 0x4c, 0xdc, 0x1a, 0x88, 0x4b, 0x2d, 0x6b, 0x6b, 0x4b, 0x36, 0x3e, 0x7c,
0x28, 0x6d, 0x58, 0xce, 0x0e, 0xbb, 0x3f, 0x33, 0x8d, 0x43, 0x2b, 0xb4, 0xa5, 0x75, 0x23, 0x02,
0x1f, 0x80, 0x7c, 0xc7, 0xb7, 0x85, 0x07, 0xb0, 0x4f, 0x5c, 0x85, 0x72, 0x93, 0x06, 0xa6, 0x6f,
0x79, 0x62, 0xff, 0x79, 0xd3, 0x58, 0x19, 0x62, 0xfb, 0x60, 0x99, 0xae, 0xb3, 0x6e, 0x93, 0x20,
0x90, 0x09, 0x28, 0x1e, 0xd0, 0x5f, 0x85, 0x05, 0x26, 0x33, 0x51, 0xf3, 0x6c, 0x5a, 0xcd, 0xc3,
0x29, 0xf8, 0x12, 0x9e, 0x44, 0x4c, 0xe0, 0x05, 0x96, 0xf7, 0x2f, 0x7b, 0x9e, 0x60, 0x32, 0x66,
0x39, 0x94, 0x1f, 0x94, 0x3f, 0x07, 0xf6, 0x4a, 0x1b, 0x7f, 0x3b, 0x0e, 0x58, 0x3d, 0x27, 0xd4,
0xef, 0x5a, 0x26, 0xc5, 0xdf, 0x46, 0x30, 0xc3, 0x44, 0xe3, 0x97, 0x86, 0x1d, 0x4b, 0xee, 0xaf,
0x95, 0xe9, 0x5d, 0x84, 0x99, 0x34, 0x7d, 0xe9, 0xad, 0xbf, 0xfe, 0xe3, 0x3b, 0xb9, 0x45, 0x7c,
0x88, 0xbf, 0x70, 0x75, 0x2f, 0xa8, 0xaf, 0x4d, 0x01, 0x7e, 0x1b, 0x01, 0x16, 0x75, 0x90, 0xf2,
0x86, 0x80, 0xcf, 0x0e, 0x83, 0x38, 0xe0, 0xad, 0xa1, 0xf2, 0x92, 0x92, 0x55, 0x6a, 0xa6, 0xeb,
0x53, 0x96, 0x43, 0xf8, 0x04, 0x0e, 0x60, 0x85, 0x03, 0x38, 0x81, 0xf5, 0x41, 0x00, 0xea, 0x8f,
0x99, 0x45, 0x9f, 0xd4, 0x69, 0x24, 0xf7, 0x5d, 0x04, 0x85, 0x07, 0xfc, 0x0e, 0x31, 0xc2, 0x48,
0x9b, 0x53, 0x33, 0x12, 0x17, 0xc7, 0xd1, 0xea, 0xc7, 0x39, 0xd2, 0x97, 0xf0, 0x11, 0x89, 0x34,
0x08, 0x7d, 0x4a, 0xda, 0x29, 0xc0, 0xe7, 0x11, 0x7e, 0x0f, 0x41, 0x31, 0x6a, 0x1e, 0xe3, 0x93,
0xc3, 0x50, 0xa6, 0x9a, 0xcb, 0x95, 0xe9, 0x75, 0x62, 0xf5, 0x33, 0x1c, 0xe3, 0x71, 0x7d, 0xe0,
0x76, 0xae, 0xa5, 0xfa, 0xb4, 0xef, 0x20, 0xc8, 0xdf, 0xa0, 0x23, 0xfd, 0x6d, 0x8a, 0xe0, 0xfa,
0x0c, 0x38, 0x60, 0xab, 0xf1, 0x8f, 0x11, 0xbc, 0x78, 0x83, 0x86, 0x83, 0xd3, 0x23, 0x5e, 0x1e,
0x9d, 0xb3, 0x84, 0xdb, 0x9d, 0x1d, 0x63, 0x66, 0x9c, 0x17, 0xea, 0x1c, 0xd9, 0x19, 0x7c, 0x3a,
0xcb, 0x09, 0x83, 0x5d, 0xc7, 0x7c, 0x24, 0x70, 0xfc, 0x09, 0xc1, 0x81, 0xde, 0xb7, 0x3e, 0x9c,
0x4e, 0xa8, 0x03, 0x9f, 0x02, 0x2b, 0x77, 0x26, 0x8d, 0xb2, 0x69, 0xa6, 0xfa, 0x65, 0x8e, 0xfc,
0x15, 0xfc, 0x72, 0x16, 0xf2, 0xb8, 0x13, 0x57, 0x7f, 0x2c, 0x3f, 0x9f, 0xf0, 0x77, 0x69, 0x0e,
0xfb, 0xcf, 0x08, 0x0e, 0x49, 0xbe, 0xeb, 0xdb, 0xc4, 0x0f, 0xaf, 0x52, 0x56, 0x43, 0x07, 0x63,
0xe9, 0x33, 0x61, 0xd6, 0x50, 0xe5, 0xe9, 0xd7, 0xb8, 0x2e, 0x9f, 0xc2, 0xaf, 0xed, 0x59, 0x17,
0x93, 0xb1, 0x69, 0x0a, 0xd8, 0x6f, 0x21, 0x98, 0xbf, 0x41, 0xc3, 0xdb, 0x71, 0x37, 0xf8, 0xe4,
0x58, 0x2f, 0x4c, 0x95, 0xa5, 0x9a, 0xf2, 0x1c, 0x2e, 0x7f, 0x8a, 0x5d, 0x64, 0x95, 0x83, 0x3b,
0x8d, 0x4f, 0x66, 0x81, 0x4b, 0x3a, 0xd0, 0xef, 0x22, 0x38, 0xac, 0x82, 0x48, 0x5e, 0xe6, 0x3e,
0xb1, 0xb7, 0xf7, 0x2e, 0xf1, 0x6a, 0x36, 0x02, 0x5d, 0x83, 0xa3, 0x3b, 0xa7, 0x0f, 0x76, 0xe0,
0x76, 0x1f, 0x8a, 0x35, 0xb4, 0xb2, 0x8c, 0xf0, 0xef, 0x11, 0x14, 0xa3, 0x66, 0xec, 0x70, 0x1b,
0xa5, 0x5e, 0x92, 0xa6, 0x19, 0x0d, 0xc4, 0x6e, 0x57, 0xce, 0x0f, 0x36, 0xa8, 0xba, 0x5e, 0xba,
0x6a, 0x8d, 0x5b, 0x39, 0x1d, 0xc6, 0x7e, 0x85, 0x00, 0x92, 0x86, 0x32, 0x3e, 0x93, 0xad, 0x87,
0xd2, 0x74, 0xae, 0x4c, 0xb7, 0xa5, 0xac, 0xd7, 0xb8, 0x3e, 0xcb, 0x95, 0x6a, 0x66, 0x0c, 0xf1,
0xa8, 0xb9, 0x16, 0x35, 0x9f, 0x7f, 0x84, 0xa0, 0xc0, 0xfb, 0x78, 0xf8, 0xc4, 0x30, 0xcc, 0x6a,
0x9b, 0x6f, 0x9a, 0xa6, 0x3f, 0xc5, 0xa1, 0x56, 0x1b, 0x59, 0x81, 0x78, 0x0d, 0xad, 0xe0, 0x2e,
0x14, 0xa3, 0xce, 0xd9, 0x70, 0xf7, 0x48, 0x75, 0xd6, 0x2a, 0xd5, 0x8c, 0xc2, 0x20, 0x72, 0x54,
0x91, 0x03, 0x56, 0x46, 0xe5, 0x80, 0x19, 0x16, 0xa6, 0xf1, 0xf1, 0xac, 0x20, 0xfe, 0x7f, 0x30,
0xcc, 0x59, 0x8e, 0xee, 0xa4, 0x5e, 0x1d, 0x95, 0x07, 0x98, 0x75, 0xbe, 0x8b, 0xe0, 0x40, 0x6f,
0x71, 0x8d, 0x8f, 0xf4, 0xc4, 0x4c, 0xf5, 0xae, 0x51, 0x49, 0x5b, 0x71, 0x58, 0x61, 0xae, 0x7f,
0x9a, 0xa3, 0x58, 0xc3, 0x97, 0x46, 0x9e, 0x8c, 0x3b, 0x32, 0xea, 0x30, 0x46, 0xab, 0xc9, 0xeb,
0xd8, 0xaf, 0x11, 0xcc, 0x4b, 0xbe, 0xf7, 0x7c, 0x4a, 0xb3, 0x61, 0x4d, 0xef, 0x20, 0x30, 0x59,
0xfa, 0xab, 0x1c, 0xfe, 0x27, 0xf1, 0xc5, 0x31, 0xe1, 0x4b, 0xd8, 0xab, 0x21, 0x43, 0xfa, 0x07,
0x04, 0x07, 0x1f, 0x44, 0x7e, 0xff, 0x21, 0xe1, 0x5f, 0xe7, 0xf8, 0x5f, 0xc3, 0xaf, 0x64, 0xd4,
0x79, 0xa3, 0xd4, 0x38, 0x8f, 0xf0, 0x2f, 0x10, 0x94, 0xe4, 0xab, 0x0a, 0x3e, 0x3d, 0xf4, 0x60,
0xa4, 0xdf, 0x5d, 0xa6, 0xe9, 0xcc, 0xa2, 0xa8, 0xd1, 0x4f, 0x64, 0xa6, 0x53, 0x21, 0x9f, 0x39,
0xf4, 0x3b, 0x08, 0x70, 0x7c, 0x67, 0x8e, 0x6f, 0xd1, 0xf8, 0x54, 0x4a, 0xd4, 0xd0, 0xc6, 0x4c,
0xe5, 0xf4, 0xc8, 0x79, 0xe9, 0x54, 0xba, 0x92, 0x99, 0x4a, 0xdd, 0x58, 0xfe, 0x37, 0x10, 0x94,
0x6f, 0xd0, 0xf8, 0x0e, 0x92, 0x61, 0xcb, 0xf4, 0xa3, 0x50, 0x65, 0x79, 0xf4, 0x44, 0x81, 0xe8,
0x1c, 0x47, 0x74, 0x0a, 0x67, 0x9b, 0x4a, 0x02, 0xf8, 0x3e, 0x82, 0x85, 0xbb, 0xaa, 0x8b, 0xe2,
0x73, 0xa3, 0x24, 0xa5, 0x22, 0xf9, 0xf8, 0xb8, 0x3e, 0xce, 0x71, 0xad, 0xea, 0x63, 0xe1, 0x5a,
0x13, 0xef, 0x2b, 0x3f, 0x40, 0xd1, 0x25, 0xb6, 0xa7, 0x9f, 0xfd, 0xbf, 0xda, 0x2d, 0xa3, 0x2d,
0xae, 0x5f, 0xe4, 0xf8, 0x6a, 0xf8, 0xdc, 0x38, 0xf8, 0xea, 0xa2, 0xc9, 0x8d, 0xbf, 0x87, 0xe0,
0x20, 0x7f, 0x6b, 0x50, 0x19, 0xf7, 0xa4, 0x98, 0x61, 0x2f, 0x13, 0x63, 0xa4, 0x18, 0x11, 0x7f,
0xf4, 0x3d, 0x81, 0x5a, 0x93, 0xef, 0x08, 0xdf, 0x44, 0xb0, 0x4f, 0x26, 0x35, 0xb1, 0xbb, 0xab,
0xa3, 0x0c, 0xb7, 0xd7, 0x24, 0x28, 0xdc, 0x6d, 0x65, 0x3c, 0x77, 0x7b, 0x0f, 0xc1, 0xac, 0xe8,
0xe6, 0x67, 0x94, 0x0a, 0x4a, 0xbb, 0xbf, 0xd2, 0xd3, 0xe3, 0x10, 0xcd, 0x60, 0xfd, 0x8b, 0x5c,
0xec, 0x7d, 0x5c, 0xcf, 0x12, 0xeb, 0xb9, 0xcd, 0xa0, 0xfe, 0x58, 0x74, 0x62, 0x9f, 0xd4, 0x6d,
0xb7, 0x15, 0xbc, 0xa1, 0xe3, 0xcc, 0x84, 0xc8, 0xe6, 0x9c, 0x47, 0x38, 0x84, 0x39, 0xe6, 0x1c,
0xbc, 0x71, 0x82, 0xab, 0x3d, 0x6d, 0x96, 0xbe, 0x9e, 0x4a, 0xa5, 0xd2, 0xd7, 0x88, 0x49, 0x32,
0xa0, 0xb8, 0xc6, 0xe2, 0x63, 0x99, 0x62, 0xb9, 0xa0, 0xb7, 0x11, 0x1c, 0x54, 0xbd, 0x3d, 0x12,
0x3f, 0xb6, 0xaf, 0x67, 0xa1, 0x10, 0x45, 0x35, 0x5e, 0x19, 0xcb, 0x91, 0x38, 0x9c, 0x2b, 0xd7,
0xff, 0xf8, 0xec, 0x28, 0x7a, 0xff, 0xd9, 0x51, 0xf4, 0xf7, 0x67, 0x47, 0xd1, 0x1b, 0x97, 0xc6,
0xfb, 0x8f, 0xaf, 0x69, 0x5b, 0xd4, 0x09, 0x55, 0xf6, 0xff, 0x0d, 0x00, 0x00, 0xff, 0xff, 0x57,
0x9a, 0x85, 0xd1, 0xc9, 0x2c, 0x00, 0x00,
}
// Reference imports to suppress errors if they are not otherwise used.
@@ -4482,21 +4503,20 @@ func (m *ApplicationManifestQuery) MarshalToSizedBuffer(dAtA []byte) (int, error
i -= len(m.XXX_unrecognized)
copy(dAtA[i:], m.XXX_unrecognized)
}
if len(m.RevisionSourceMappings) > 0 {
for k := range m.RevisionSourceMappings {
v := m.RevisionSourceMappings[k]
baseI := i
i -= len(v)
copy(dAtA[i:], v)
i = encodeVarintApplication(dAtA, i, uint64(len(v)))
if len(m.Revisions) > 0 {
for iNdEx := len(m.Revisions) - 1; iNdEx >= 0; iNdEx-- {
i -= len(m.Revisions[iNdEx])
copy(dAtA[i:], m.Revisions[iNdEx])
i = encodeVarintApplication(dAtA, i, uint64(len(m.Revisions[iNdEx])))
i--
dAtA[i] = 0x12
i = encodeVarintApplication(dAtA, i, uint64(k))
dAtA[i] = 0x32
}
}
if len(m.SourcePositions) > 0 {
for iNdEx := len(m.SourcePositions) - 1; iNdEx >= 0; iNdEx-- {
i = encodeVarintApplication(dAtA, i, uint64(m.SourcePositions[iNdEx]))
i--
dAtA[i] = 0x8
i = encodeVarintApplication(dAtA, i, uint64(baseI-i))
i--
dAtA[i] = 0x2a
dAtA[i] = 0x28
}
}
if m.Project != nil {
@@ -4978,6 +4998,22 @@ func (m *ApplicationSyncRequest) MarshalToSizedBuffer(dAtA []byte) (int, error)
i -= len(m.XXX_unrecognized)
copy(dAtA[i:], m.XXX_unrecognized)
}
if len(m.Revisions) > 0 {
for iNdEx := len(m.Revisions) - 1; iNdEx >= 0; iNdEx-- {
i -= len(m.Revisions[iNdEx])
copy(dAtA[i:], m.Revisions[iNdEx])
i = encodeVarintApplication(dAtA, i, uint64(len(m.Revisions[iNdEx])))
i--
dAtA[i] = 0x7a
}
}
if len(m.SourcePositions) > 0 {
for iNdEx := len(m.SourcePositions) - 1; iNdEx >= 0; iNdEx-- {
i = encodeVarintApplication(dAtA, i, uint64(m.SourcePositions[iNdEx]))
i--
dAtA[i] = 0x70
}
}
if m.Project != nil {
i -= len(*m.Project)
copy(dAtA[i:], *m.Project)
@@ -6742,12 +6778,15 @@ func (m *ApplicationManifestQuery) Size() (n int) {
l = len(*m.Project)
n += 1 + l + sovApplication(uint64(l))
}
if len(m.RevisionSourceMappings) > 0 {
for k, v := range m.RevisionSourceMappings {
_ = k
_ = v
mapEntrySize := 1 + sovApplication(uint64(k)) + 1 + len(v) + sovApplication(uint64(len(v)))
n += mapEntrySize + 1 + sovApplication(uint64(mapEntrySize))
if len(m.SourcePositions) > 0 {
for _, e := range m.SourcePositions {
n += 1 + sovApplication(uint64(e))
}
}
if len(m.Revisions) > 0 {
for _, s := range m.Revisions {
l = len(s)
n += 1 + l + sovApplication(uint64(l))
}
}
if m.XXX_unrecognized != nil {
@@ -7003,6 +7042,17 @@ func (m *ApplicationSyncRequest) Size() (n int) {
l = len(*m.Project)
n += 1 + l + sovApplication(uint64(l))
}
if len(m.SourcePositions) > 0 {
for _, e := range m.SourcePositions {
n += 1 + sovApplication(uint64(e))
}
}
if len(m.Revisions) > 0 {
for _, s := range m.Revisions {
l = len(s)
n += 1 + l + sovApplication(uint64(l))
}
}
if m.XXX_unrecognized != nil {
n += len(m.XXX_unrecognized)
}
@@ -8728,42 +8778,8 @@ func (m *ApplicationManifestQuery) Unmarshal(dAtA []byte) error {
m.Project = &s
iNdEx = postIndex
case 5:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field RevisionSourceMappings", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowApplication
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthApplication
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthApplication
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
if m.RevisionSourceMappings == nil {
m.RevisionSourceMappings = make(map[int64]string)
}
var mapkey int64
var mapvalue string
for iNdEx < postIndex {
entryPreIndex := iNdEx
var wire uint64
if wireType == 0 {
var v int64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowApplication
@@ -8773,13 +8789,51 @@ func (m *ApplicationManifestQuery) Unmarshal(dAtA []byte) error {
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
v |= int64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
if fieldNum == 1 {
m.SourcePositions = append(m.SourcePositions, v)
} else if wireType == 2 {
var packedLen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowApplication
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
packedLen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if packedLen < 0 {
return ErrInvalidLengthApplication
}
postIndex := iNdEx + packedLen
if postIndex < 0 {
return ErrInvalidLengthApplication
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
var elementCount int
var count int
for _, integer := range dAtA[iNdEx:postIndex] {
if integer < 128 {
count++
}
}
elementCount = count
if elementCount != 0 && len(m.SourcePositions) == 0 {
m.SourcePositions = make([]int64, 0, elementCount)
}
for iNdEx < postIndex {
var v int64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowApplication
@@ -8789,56 +8843,47 @@ func (m *ApplicationManifestQuery) Unmarshal(dAtA []byte) error {
}
b := dAtA[iNdEx]
iNdEx++
mapkey |= int64(b&0x7F) << shift
v |= int64(b&0x7F) << shift
if b < 0x80 {
break
}
}
} else if fieldNum == 2 {
var stringLenmapvalue uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowApplication
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLenmapvalue |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLenmapvalue := int(stringLenmapvalue)
if intStringLenmapvalue < 0 {
return ErrInvalidLengthApplication
}
postStringIndexmapvalue := iNdEx + intStringLenmapvalue
if postStringIndexmapvalue < 0 {
return ErrInvalidLengthApplication
}
if postStringIndexmapvalue > l {
return io.ErrUnexpectedEOF
}
mapvalue = string(dAtA[iNdEx:postStringIndexmapvalue])
iNdEx = postStringIndexmapvalue
} else {
iNdEx = entryPreIndex
skippy, err := skipApplication(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLengthApplication
}
if (iNdEx + skippy) > postIndex {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
m.SourcePositions = append(m.SourcePositions, v)
}
} else {
return fmt.Errorf("proto: wrong wireType = %d for field SourcePositions", wireType)
}
case 6:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Revisions", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowApplication
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
m.RevisionSourceMappings[mapkey] = mapvalue
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthApplication
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthApplication
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Revisions = append(m.Revisions, string(dAtA[iNdEx:postIndex]))
iNdEx = postIndex
default:
iNdEx = preIndex
@@ -10304,6 +10349,114 @@ func (m *ApplicationSyncRequest) Unmarshal(dAtA []byte) error {
s := string(dAtA[iNdEx:postIndex])
m.Project = &s
iNdEx = postIndex
case 14:
if wireType == 0 {
var v int64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowApplication
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
v |= int64(b&0x7F) << shift
if b < 0x80 {
break
}
}
m.SourcePositions = append(m.SourcePositions, v)
} else if wireType == 2 {
var packedLen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowApplication
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
packedLen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if packedLen < 0 {
return ErrInvalidLengthApplication
}
postIndex := iNdEx + packedLen
if postIndex < 0 {
return ErrInvalidLengthApplication
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
var elementCount int
var count int
for _, integer := range dAtA[iNdEx:postIndex] {
if integer < 128 {
count++
}
}
elementCount = count
if elementCount != 0 && len(m.SourcePositions) == 0 {
m.SourcePositions = make([]int64, 0, elementCount)
}
for iNdEx < postIndex {
var v int64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowApplication
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
v |= int64(b&0x7F) << shift
if b < 0x80 {
break
}
}
m.SourcePositions = append(m.SourcePositions, v)
}
} else {
return fmt.Errorf("proto: wrong wireType = %d for field SourcePositions", wireType)
}
case 15:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Revisions", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowApplication
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthApplication
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthApplication
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Revisions = append(m.Revisions, string(dAtA[iNdEx:postIndex]))
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipApplication(dAtA[iNdEx:])

View File

@@ -99,6 +99,9 @@ API rule violation: names_match,github.com/argoproj/argo-cd/v2/pkg/apis/applicat
API rule violation: names_match,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,ApplicationSourcePluginParameter,String_
API rule violation: names_match,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,ClusterCacheInfo,APIsCount
API rule violation: names_match,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,ConnectionState,ModifiedAt
API rule violation: names_match,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,ErrApplicationNotAllowedToUseProject,application
API rule violation: names_match,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,ErrApplicationNotAllowedToUseProject,namespace
API rule violation: names_match,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,ErrApplicationNotAllowedToUseProject,project
API rule violation: names_match,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,HelmOptions,ValuesFileSchemes
API rule violation: names_match,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,JWTToken,ExpiresAt
API rule violation: names_match,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,JWTToken,IssuedAt

View File

@@ -17,6 +17,24 @@ import (
"k8s.io/apimachinery/pkg/runtime/schema"
)
type ErrApplicationNotAllowedToUseProject struct {
application string
namespace string
project string
}
func NewErrApplicationNotAllowedToUseProject(application, namespace, project string) error {
return &ErrApplicationNotAllowedToUseProject{
application: application,
namespace: namespace,
project: project,
}
}
func (err *ErrApplicationNotAllowedToUseProject) Error() string {
return fmt.Sprintf("application '%s' in namespace '%s' is not allowed to use project %s", err.application, err.namespace, err.project)
}
// AppProjectList is list of AppProject resources
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
type AppProjectList struct {

File diff suppressed because it is too large Load Diff

View File

@@ -904,6 +904,9 @@ message EnvEntry {
optional string value = 2;
}
message ErrApplicationNotAllowedToUseProject {
}
// ExecProviderConfig is config used to call an external command to perform cluster authentication
// See: https://godoc.org/k8s.io/client-go/tools/clientcmd/api#ExecConfig
message ExecProviderConfig {

View File

@@ -70,6 +70,7 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA
"github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ConnectionState": schema_pkg_apis_application_v1alpha1_ConnectionState(ref),
"github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.DuckTypeGenerator": schema_pkg_apis_application_v1alpha1_DuckTypeGenerator(ref),
"github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.EnvEntry": schema_pkg_apis_application_v1alpha1_EnvEntry(ref),
"github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ErrApplicationNotAllowedToUseProject": schema_pkg_apis_application_v1alpha1_ErrApplicationNotAllowedToUseProject(ref),
"github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ExecProviderConfig": schema_pkg_apis_application_v1alpha1_ExecProviderConfig(ref),
"github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.GitDirectoryGeneratorItem": schema_pkg_apis_application_v1alpha1_GitDirectoryGeneratorItem(ref),
"github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.GitFileGeneratorItem": schema_pkg_apis_application_v1alpha1_GitFileGeneratorItem(ref),
@@ -3221,6 +3222,40 @@ func schema_pkg_apis_application_v1alpha1_EnvEntry(ref common.ReferenceCallback)
}
}
func schema_pkg_apis_application_v1alpha1_ErrApplicationNotAllowedToUseProject(ref common.ReferenceCallback) common.OpenAPIDefinition {
return common.OpenAPIDefinition{
Schema: spec.Schema{
SchemaProps: spec.SchemaProps{
Type: []string{"object"},
Properties: map[string]spec.Schema{
"application": {
SchemaProps: spec.SchemaProps{
Default: "",
Type: []string{"string"},
Format: "",
},
},
"namespace": {
SchemaProps: spec.SchemaProps{
Default: "",
Type: []string{"string"},
Format: "",
},
},
"project": {
SchemaProps: spec.SchemaProps{
Default: "",
Type: []string{"string"},
Format: "",
},
},
},
Required: []string{"application", "namespace", "project"},
},
},
}
}
func schema_pkg_apis_application_v1alpha1_ExecProviderConfig(ref common.ReferenceCallback) common.OpenAPIDefinition {
return common.OpenAPIDefinition{
Schema: spec.Schema{

View File

@@ -230,11 +230,16 @@ func (a *ApplicationSpec) HasMultipleSources() bool {
return a.Sources != nil && len(a.Sources) > 0
}
func (a *ApplicationSpec) GetSourcePtr(index int) *ApplicationSource {
func (a *ApplicationSpec) GetSourcePtrByPosition(sourcePosition int) *ApplicationSource {
// if Application has multiple sources, return the first source in sources
return a.GetSourcePtrByIndex(sourcePosition - 1)
}
func (a *ApplicationSpec) GetSourcePtrByIndex(sourceIndex int) *ApplicationSource {
// if Application has multiple sources, return the first source in sources
if a.HasMultipleSources() {
if index > 0 {
return &a.Sources[index-1]
if sourceIndex > 0 {
return &a.Sources[sourceIndex]
}
return &a.Sources[0]
}

View File

@@ -3620,3 +3620,50 @@ func TestOptionalMapEquality(t *testing.T) {
})
}
}
func TestApplicationSpec_GetSourcePtrByIndex(t *testing.T) {
testCases := []struct {
name string
application ApplicationSpec
sourceIndex int
expected *ApplicationSource
}{
{
name: "HasMultipleSources_ReturnsFirstSource",
application: ApplicationSpec{
Sources: []ApplicationSource{
{RepoURL: "https://github.com/argoproj/test1.git"},
{RepoURL: "https://github.com/argoproj/test2.git"},
},
},
sourceIndex: 0,
expected: &ApplicationSource{RepoURL: "https://github.com/argoproj/test1.git"},
},
{
name: "HasMultipleSources_ReturnsSourceAtIndex",
application: ApplicationSpec{
Sources: []ApplicationSource{
{RepoURL: "https://github.com/argoproj/test1.git"},
{RepoURL: "https://github.com/argoproj/test2.git"},
},
},
sourceIndex: 1,
expected: &ApplicationSource{RepoURL: "https://github.com/argoproj/test2.git"},
},
{
name: "HasSingleSource_ReturnsSource",
application: ApplicationSpec{
Source: &ApplicationSource{RepoURL: "https://github.com/argoproj/test.git"},
},
sourceIndex: 0,
expected: &ApplicationSource{RepoURL: "https://github.com/argoproj/test.git"},
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
actual := tc.application.GetSourcePtrByIndex(tc.sourceIndex)
assert.Equal(t, tc.expected, actual)
})
}
}

View File

@@ -1862,6 +1862,22 @@ func (in *EnvEntry) DeepCopy() *EnvEntry {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ErrApplicationNotAllowedToUseProject) DeepCopyInto(out *ErrApplicationNotAllowedToUseProject) {
*out = *in
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ErrApplicationNotAllowedToUseProject.
func (in *ErrApplicationNotAllowedToUseProject) DeepCopy() *ErrApplicationNotAllowedToUseProject {
if in == nil {
return nil
}
out := new(ErrApplicationNotAllowedToUseProject)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ExecProviderConfig) DeepCopyInto(out *ExecProviderConfig) {
*out = *in

View File

@@ -557,6 +557,7 @@ type ResolveRevisionRequest struct {
Repo *v1alpha1.Repository `protobuf:"bytes,1,opt,name=repo,proto3" json:"repo,omitempty"`
App *v1alpha1.Application `protobuf:"bytes,2,opt,name=app,proto3" json:"app,omitempty"`
AmbiguousRevision string `protobuf:"bytes,3,opt,name=ambiguousRevision,proto3" json:"ambiguousRevision,omitempty"`
SourceIndex int64 `protobuf:"varint,4,opt,name=sourceIndex,proto3" json:"sourceIndex,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@@ -616,6 +617,13 @@ func (m *ResolveRevisionRequest) GetAmbiguousRevision() string {
return ""
}
func (m *ResolveRevisionRequest) GetSourceIndex() int64 {
if m != nil {
return m.SourceIndex
}
return 0
}
// ResolveRevisionResponse
type ResolveRevisionResponse struct {
// returns the resolved revision
@@ -2398,150 +2406,151 @@ func init() {
}
var fileDescriptor_dd8723cfcc820480 = []byte{
// 2277 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x1a, 0x5d, 0x8f, 0x1b, 0x49,
0xd1, 0xe3, 0xaf, 0xb5, 0xcb, 0x9b, 0x5d, 0x6f, 0x5f, 0xb2, 0x99, 0xf8, 0x92, 0xd5, 0xde, 0x40,
0xa2, 0x5c, 0x72, 0x67, 0x2b, 0x1b, 0xdd, 0x05, 0x72, 0xc7, 0xa1, 0xbd, 0x5c, 0xb2, 0x9b, 0x4b,
0x36, 0x59, 0x26, 0x39, 0x50, 0x20, 0x80, 0xda, 0xe3, 0xf6, 0x78, 0xce, 0xe3, 0x99, 0xce, 0x4c,
0xcf, 0x9e, 0x1c, 0x89, 0x07, 0x04, 0xe2, 0x27, 0xf0, 0xc0, 0xaf, 0x40, 0x42, 0x88, 0x47, 0x1e,
0x10, 0x1f, 0x8f, 0x88, 0x3f, 0x00, 0xca, 0x0b, 0x12, 0xbf, 0x02, 0x75, 0x4f, 0xcf, 0xa7, 0xc7,
0xce, 0x1e, 0x4e, 0xf6, 0x80, 0x97, 0xdd, 0xe9, 0xea, 0xea, 0xaa, 0xea, 0xea, 0xfa, 0xec, 0x36,
0x5c, 0xf2, 0x08, 0x75, 0x7d, 0xe2, 0x1d, 0x11, 0xaf, 0x27, 0x3e, 0x2d, 0xe6, 0x7a, 0xd3, 0xd4,
0x67, 0x97, 0x7a, 0x2e, 0x73, 0x11, 0x24, 0x90, 0xce, 0x7d, 0xd3, 0x62, 0xa3, 0xa0, 0xdf, 0x35,
0xdc, 0x49, 0x0f, 0x7b, 0xa6, 0x4b, 0x3d, 0xf7, 0x73, 0xf1, 0xf1, 0xae, 0x31, 0xe8, 0x1d, 0xed,
0xf4, 0xe8, 0xd8, 0xec, 0x61, 0x6a, 0xf9, 0x3d, 0x4c, 0xa9, 0x6d, 0x19, 0x98, 0x59, 0xae, 0xd3,
0x3b, 0xba, 0x86, 0x6d, 0x3a, 0xc2, 0xd7, 0x7a, 0x26, 0x71, 0x88, 0x87, 0x19, 0x19, 0x84, 0x94,
0x3b, 0x6f, 0x9a, 0xae, 0x6b, 0xda, 0xa4, 0x27, 0x46, 0xfd, 0x60, 0xd8, 0x23, 0x13, 0xca, 0x24,
0x5b, 0xed, 0x5f, 0xab, 0xb0, 0x7e, 0x80, 0x1d, 0x6b, 0x48, 0x7c, 0xa6, 0x93, 0x67, 0x01, 0xf1,
0x19, 0x7a, 0x0a, 0x55, 0x2e, 0x8c, 0xaa, 0x6c, 0x2b, 0x97, 0x5b, 0x3b, 0xfb, 0xdd, 0x44, 0x9a,
0x6e, 0x24, 0x8d, 0xf8, 0xf8, 0xb1, 0x31, 0xe8, 0x1e, 0xed, 0x74, 0xe9, 0xd8, 0xec, 0x72, 0x69,
0xba, 0x29, 0x69, 0xba, 0x91, 0x34, 0x5d, 0x3d, 0xde, 0x96, 0x2e, 0xa8, 0xa2, 0x0e, 0x34, 0x3c,
0x72, 0x64, 0xf9, 0x96, 0xeb, 0xa8, 0xe5, 0x6d, 0xe5, 0x72, 0x53, 0x8f, 0xc7, 0x48, 0x85, 0x15,
0xc7, 0xbd, 0x85, 0x8d, 0x11, 0x51, 0x2b, 0xdb, 0xca, 0xe5, 0x86, 0x1e, 0x0d, 0xd1, 0x36, 0xb4,
0x30, 0xa5, 0xf7, 0x71, 0x9f, 0xd8, 0xf7, 0xc8, 0x54, 0xad, 0x8a, 0x85, 0x69, 0x10, 0x5f, 0x8b,
0x29, 0x7d, 0x80, 0x27, 0x44, 0xad, 0x89, 0xd9, 0x68, 0x88, 0xce, 0x43, 0xd3, 0xc1, 0x13, 0xe2,
0x53, 0x6c, 0x10, 0xb5, 0x21, 0xe6, 0x12, 0x00, 0xfa, 0x09, 0x6c, 0xa4, 0x04, 0x7f, 0xe4, 0x06,
0x9e, 0x41, 0x54, 0x10, 0x5b, 0x7f, 0xb8, 0xdc, 0xd6, 0x77, 0xf3, 0x64, 0xf5, 0x59, 0x4e, 0xe8,
0x47, 0x50, 0x13, 0x27, 0xaf, 0xb6, 0xb6, 0x2b, 0xaf, 0x54, 0xdb, 0x21, 0x59, 0xe4, 0xc0, 0x0a,
0xb5, 0x03, 0xd3, 0x72, 0x7c, 0x75, 0x55, 0x70, 0x78, 0xbc, 0x1c, 0x87, 0x5b, 0xae, 0x33, 0xb4,
0xcc, 0x03, 0xec, 0x60, 0x93, 0x4c, 0x88, 0xc3, 0x0e, 0x05, 0x71, 0x3d, 0x62, 0x82, 0x9e, 0x43,
0x7b, 0x1c, 0xf8, 0xcc, 0x9d, 0x58, 0xcf, 0xc9, 0x43, 0xca, 0xd7, 0xfa, 0xea, 0x29, 0xa1, 0xcd,
0x07, 0xcb, 0x31, 0xbe, 0x97, 0xa3, 0xaa, 0xcf, 0xf0, 0xe1, 0x46, 0x32, 0x0e, 0xfa, 0xe4, 0xbb,
0xc4, 0x13, 0xd6, 0xb5, 0x16, 0x1a, 0x49, 0x0a, 0x14, 0x9a, 0x91, 0x25, 0x47, 0xbe, 0xba, 0xbe,
0x5d, 0x09, 0xcd, 0x28, 0x06, 0xa1, 0xcb, 0xb0, 0x7e, 0x44, 0x3c, 0x6b, 0x38, 0x7d, 0x64, 0x99,
0x0e, 0x66, 0x81, 0x47, 0xd4, 0xb6, 0x30, 0xc5, 0x3c, 0x18, 0x4d, 0xe0, 0xd4, 0x88, 0xd8, 0x13,
0xae, 0xf2, 0x5b, 0x1e, 0x19, 0xf8, 0xea, 0x86, 0xd0, 0xef, 0xde, 0xf2, 0x27, 0x28, 0xc8, 0xe9,
0x59, 0xea, 0x5c, 0x30, 0xc7, 0xd5, 0xa5, 0xa7, 0x84, 0x3e, 0x82, 0x42, 0xc1, 0x72, 0x60, 0x74,
0x09, 0xd6, 0x98, 0x87, 0x8d, 0xb1, 0xe5, 0x98, 0x07, 0x84, 0x8d, 0xdc, 0x81, 0xfa, 0x86, 0xd0,
0x44, 0x0e, 0x8a, 0x0c, 0x40, 0xc4, 0xc1, 0x7d, 0x9b, 0x0c, 0x42, 0x5b, 0x7c, 0x3c, 0xa5, 0xc4,
0x57, 0x4f, 0x8b, 0x5d, 0x5c, 0xef, 0xa6, 0x22, 0x54, 0x2e, 0x40, 0x74, 0x6f, 0xcf, 0xac, 0xba,
0xed, 0x30, 0x6f, 0xaa, 0x17, 0x90, 0x43, 0x63, 0x68, 0xf1, 0x7d, 0x44, 0xa6, 0x70, 0x46, 0x98,
0xc2, 0xdd, 0xe5, 0x74, 0xb4, 0x9f, 0x10, 0xd4, 0xd3, 0xd4, 0x51, 0x17, 0xd0, 0x08, 0xfb, 0x07,
0x81, 0xcd, 0x2c, 0x6a, 0x93, 0x50, 0x0c, 0x5f, 0xdd, 0x14, 0x6a, 0x2a, 0x98, 0x41, 0xf7, 0x00,
0x3c, 0x32, 0x8c, 0xf0, 0xce, 0x8a, 0x9d, 0x5f, 0x5d, 0xb4, 0x73, 0x3d, 0xc6, 0x0e, 0x77, 0x9c,
0x5a, 0xce, 0x99, 0xf3, 0x6d, 0x10, 0x83, 0x49, 0x6f, 0x17, 0x6e, 0xad, 0x0a, 0x13, 0x2b, 0x98,
0xe1, 0xb6, 0x28, 0xa1, 0x22, 0x68, 0x9d, 0x0b, 0xad, 0x35, 0x05, 0xea, 0xdc, 0x86, 0xb3, 0x73,
0x54, 0x8d, 0xda, 0x50, 0x19, 0x93, 0xa9, 0x08, 0xd1, 0x4d, 0x9d, 0x7f, 0xa2, 0xd3, 0x50, 0x3b,
0xc2, 0x76, 0x40, 0x44, 0x50, 0x6d, 0xe8, 0xe1, 0xe0, 0x66, 0xf9, 0x1b, 0x4a, 0xe7, 0x17, 0x0a,
0xac, 0xe7, 0x04, 0x2f, 0x58, 0xff, 0xc3, 0xf4, 0xfa, 0x57, 0x60, 0xc6, 0xc3, 0xc7, 0xd8, 0x33,
0x09, 0x4b, 0x09, 0xa2, 0xfd, 0x4d, 0x01, 0x35, 0xa7, 0xd1, 0xef, 0x59, 0x6c, 0x74, 0xc7, 0xb2,
0x89, 0x8f, 0x6e, 0xc0, 0x8a, 0x17, 0xc2, 0x64, 0xe2, 0x79, 0x73, 0xc1, 0x41, 0xec, 0x97, 0xf4,
0x08, 0x1b, 0x7d, 0x04, 0x8d, 0x09, 0x61, 0x78, 0x80, 0x19, 0x96, 0xb2, 0x6f, 0x17, 0xad, 0xe4,
0x5c, 0x0e, 0x24, 0xde, 0x7e, 0x49, 0x8f, 0xd7, 0xa0, 0xf7, 0xa0, 0x66, 0x8c, 0x02, 0x67, 0x2c,
0x52, 0x4e, 0x6b, 0xe7, 0xc2, 0xbc, 0xc5, 0xb7, 0x38, 0xd2, 0x7e, 0x49, 0x0f, 0xb1, 0x3f, 0xae,
0x43, 0x95, 0x62, 0x8f, 0x69, 0x77, 0xe0, 0x74, 0x11, 0x0b, 0x9e, 0xe7, 0x8c, 0x11, 0x31, 0xc6,
0x7e, 0x30, 0x91, 0x6a, 0x8e, 0xc7, 0x08, 0x41, 0xd5, 0xb7, 0x9e, 0x87, 0xaa, 0xae, 0xe8, 0xe2,
0x5b, 0x7b, 0x1b, 0x36, 0x66, 0xb8, 0xf1, 0x43, 0x0d, 0x65, 0xe3, 0x14, 0x56, 0x25, 0x6b, 0x2d,
0x80, 0x33, 0x8f, 0x85, 0x2e, 0xe2, 0x60, 0x7f, 0x12, 0x99, 0x5b, 0xdb, 0x87, 0xcd, 0x3c, 0x5b,
0x9f, 0xba, 0x8e, 0x4f, 0xb8, 0xe9, 0x8b, 0xe8, 0x68, 0x91, 0x41, 0x32, 0x2b, 0xa4, 0x68, 0xe8,
0x05, 0x33, 0xda, 0x4f, 0xcb, 0xb0, 0xa9, 0x13, 0xdf, 0xb5, 0x8f, 0x48, 0x14, 0xba, 0x4e, 0xa6,
0xf8, 0xf8, 0x01, 0x54, 0x30, 0xa5, 0xd2, 0x4c, 0xee, 0xbe, 0xb2, 0xf4, 0xae, 0x73, 0xaa, 0xe8,
0x1d, 0xd8, 0xc0, 0x93, 0xbe, 0x65, 0x06, 0x6e, 0xe0, 0x47, 0xdb, 0x12, 0x46, 0xd5, 0xd4, 0x67,
0x27, 0x34, 0x03, 0xce, 0xce, 0xa8, 0x40, 0xaa, 0x33, 0x5d, 0x22, 0x29, 0xb9, 0x12, 0xa9, 0x90,
0x49, 0x79, 0x1e, 0x93, 0x3f, 0x29, 0xd0, 0x4e, 0x5c, 0x47, 0x92, 0x3f, 0x0f, 0xcd, 0x89, 0x84,
0xf9, 0xaa, 0x22, 0xe2, 0x53, 0x02, 0xc8, 0x56, 0x4b, 0xe5, 0x7c, 0xb5, 0xb4, 0x09, 0xf5, 0xb0,
0x98, 0x95, 0x1b, 0x93, 0xa3, 0x8c, 0xc8, 0xd5, 0x9c, 0xc8, 0x5b, 0x00, 0x7e, 0x1c, 0xbf, 0xd4,
0xba, 0x98, 0x4d, 0x41, 0x90, 0x06, 0xab, 0x61, 0x6e, 0xd5, 0x89, 0x1f, 0xd8, 0x4c, 0x5d, 0x11,
0x18, 0x19, 0x98, 0xe6, 0xc2, 0xfa, 0x7d, 0x8b, 0xef, 0x61, 0xe8, 0x9f, 0x8c, 0xb1, 0xbf, 0x0f,
0x55, 0xce, 0x8c, 0x6f, 0xac, 0xef, 0x61, 0xc7, 0x18, 0x91, 0x48, 0x57, 0xf1, 0x98, 0xbb, 0x31,
0xc3, 0xa6, 0xaf, 0x96, 0x05, 0x5c, 0x7c, 0x6b, 0xbf, 0x2b, 0x87, 0x92, 0xee, 0x52, 0xea, 0x7f,
0xf5, 0x05, 0x75, 0x71, 0x8a, 0xaf, 0xcc, 0xa6, 0xf8, 0x9c, 0xc8, 0x5f, 0x26, 0xc5, 0xbf, 0xa2,
0x34, 0xa5, 0x05, 0xb0, 0xb2, 0x4b, 0x29, 0x17, 0x04, 0x5d, 0x83, 0x2a, 0xa6, 0x34, 0x54, 0x78,
0x2e, 0x22, 0x4b, 0x14, 0xfe, 0x5f, 0x8a, 0x24, 0x50, 0x3b, 0x37, 0xa0, 0x19, 0x83, 0x5e, 0xc6,
0xb6, 0x99, 0x66, 0xbb, 0x0d, 0x10, 0xd6, 0xb0, 0x77, 0x9d, 0xa1, 0xcb, 0x8f, 0x94, 0x1b, 0xbb,
0x5c, 0x2a, 0xbe, 0xb5, 0x9b, 0x11, 0x86, 0x90, 0xed, 0x1d, 0xa8, 0x59, 0x8c, 0x4c, 0x22, 0xe1,
0x36, 0xd3, 0xc2, 0x25, 0x84, 0xf4, 0x10, 0x49, 0xfb, 0x73, 0x03, 0xce, 0xf1, 0x13, 0x7b, 0x24,
0xdc, 0x64, 0x97, 0xd2, 0x4f, 0x08, 0xc3, 0x96, 0xed, 0x7f, 0x27, 0x20, 0xde, 0xf4, 0x35, 0x1b,
0x86, 0x09, 0xf5, 0xd0, 0xcb, 0x64, 0xbc, 0x7b, 0xe5, 0xed, 0x8c, 0x24, 0x9f, 0xf4, 0x30, 0x95,
0xd7, 0xd3, 0xc3, 0x14, 0xf5, 0x14, 0xd5, 0x13, 0xea, 0x29, 0xe6, 0xb7, 0x95, 0xa9, 0x66, 0xb5,
0x9e, 0x6d, 0x56, 0x0b, 0x4a, 0xf5, 0x95, 0xe3, 0x96, 0xea, 0x8d, 0xc2, 0x52, 0x7d, 0x52, 0xe8,
0xc7, 0x4d, 0xa1, 0xee, 0x6f, 0xa5, 0x2d, 0x70, 0xae, 0xad, 0x2d, 0x53, 0xb4, 0xc3, 0x6b, 0x2d,
0xda, 0x3f, 0xcb, 0x14, 0xe1, 0x61, 0x1b, 0xfc, 0xde, 0xf1, 0xf6, 0xb4, 0xa0, 0x1c, 0xff, 0xbf,
0x2b, 0x9e, 0x7f, 0x2e, 0x6a, 0x26, 0xea, 0x26, 0x3a, 0x88, 0x13, 0x3a, 0xcf, 0x43, 0x3c, 0xb5,
0xca, 0xa0, 0xc5, 0xbf, 0xd1, 0x55, 0xa8, 0x72, 0x25, 0xcb, 0xa2, 0xf6, 0x6c, 0x5a, 0x9f, 0xfc,
0x24, 0x76, 0x29, 0x7d, 0x44, 0x89, 0xa1, 0x0b, 0x24, 0x74, 0x13, 0x9a, 0xb1, 0xe1, 0x4b, 0xcf,
0x3a, 0x9f, 0x5e, 0x11, 0xfb, 0x49, 0xb4, 0x2c, 0x41, 0xe7, 0x6b, 0x07, 0x96, 0x47, 0x0c, 0x51,
0xf2, 0xd5, 0x66, 0xd7, 0x7e, 0x12, 0x4d, 0xc6, 0x6b, 0x63, 0x74, 0x74, 0x0d, 0xea, 0xe1, 0xbd,
0x81, 0xf0, 0xa0, 0xd6, 0xce, 0xb9, 0xd9, 0x60, 0x1a, 0xad, 0x92, 0x88, 0xda, 0x1f, 0x15, 0x78,
0x2b, 0x31, 0x88, 0xc8, 0x9b, 0xa2, 0xaa, 0xfb, 0xab, 0xcf, 0xb8, 0x97, 0x60, 0x4d, 0x94, 0xf9,
0xc9, 0xf5, 0x41, 0x78, 0x93, 0x95, 0x83, 0x6a, 0xbf, 0x55, 0xe0, 0xe2, 0xec, 0x3e, 0x6e, 0x8d,
0xb0, 0xc7, 0xe2, 0xe3, 0x3d, 0x89, 0xbd, 0x44, 0x09, 0xaf, 0x9c, 0x24, 0xbc, 0xcc, 0xfe, 0x2a,
0xd9, 0xfd, 0x69, 0xbf, 0x2f, 0x43, 0x2b, 0x65, 0x40, 0x45, 0x09, 0x93, 0x17, 0x7c, 0xc2, 0x6e,
0x45, 0x63, 0x27, 0x92, 0x42, 0x53, 0x4f, 0x41, 0xd0, 0x18, 0x80, 0x62, 0x0f, 0x4f, 0x08, 0x23,
0x1e, 0x8f, 0xe4, 0xdc, 0xe3, 0xef, 0x2d, 0x1f, 0x5d, 0x0e, 0x23, 0x9a, 0x7a, 0x8a, 0x3c, 0xaf,
0x58, 0x05, 0x6b, 0x5f, 0xc6, 0x6f, 0x39, 0x42, 0x5f, 0xc0, 0xda, 0xd0, 0xb2, 0xc9, 0x61, 0x22,
0x48, 0x5d, 0x08, 0xf2, 0x70, 0x79, 0x41, 0xee, 0xa4, 0xe9, 0xea, 0x39, 0x36, 0xda, 0x15, 0x68,
0xe7, 0xfd, 0x89, 0x0b, 0x69, 0x4d, 0xb0, 0x19, 0x6b, 0x4b, 0x8e, 0x34, 0x04, 0xed, 0xbc, 0xff,
0x68, 0x7f, 0x2f, 0xc3, 0x99, 0x98, 0xdc, 0xae, 0xe3, 0xb8, 0x81, 0x63, 0x88, 0xab, 0xb8, 0xc2,
0xb3, 0x38, 0x0d, 0x35, 0x66, 0x31, 0x3b, 0x2e, 0x7c, 0xc4, 0x80, 0xe7, 0x2e, 0xe6, 0xba, 0x36,
0xb3, 0xa8, 0x3c, 0xe0, 0x68, 0x18, 0x9e, 0xfd, 0xb3, 0xc0, 0xf2, 0xc8, 0x40, 0x44, 0x82, 0x86,
0x1e, 0x8f, 0xf9, 0x1c, 0xaf, 0x6a, 0x44, 0x19, 0x1f, 0x2a, 0x33, 0x1e, 0x0b, 0xbb, 0x77, 0x6d,
0x9b, 0x18, 0x5c, 0x1d, 0xa9, 0x42, 0x3f, 0x07, 0x15, 0x0d, 0x04, 0xf3, 0x2c, 0xc7, 0x94, 0x65,
0xbe, 0x1c, 0x71, 0x39, 0xb1, 0xe7, 0xe1, 0xa9, 0xda, 0x10, 0x0a, 0x08, 0x07, 0xe8, 0x43, 0xa8,
0x4c, 0x30, 0x95, 0x89, 0xee, 0x4a, 0x26, 0x3a, 0x14, 0x69, 0xa0, 0x7b, 0x80, 0x69, 0x98, 0x09,
0xf8, 0xb2, 0xce, 0xfb, 0xd0, 0x88, 0x00, 0x5f, 0xaa, 0x24, 0xfc, 0x1c, 0x4e, 0x65, 0x82, 0x0f,
0x7a, 0x02, 0x9b, 0x89, 0x45, 0xa5, 0x19, 0xca, 0x22, 0xf0, 0xad, 0x97, 0x4a, 0xa6, 0xcf, 0x21,
0xa0, 0x3d, 0x83, 0x0d, 0x6e, 0x32, 0xc2, 0xf1, 0x4f, 0xa8, 0xb5, 0xf9, 0x00, 0x9a, 0x31, 0xcb,
0x42, 0x9b, 0xe9, 0x40, 0xe3, 0x28, 0xba, 0x22, 0x0d, 0x7b, 0x9b, 0x78, 0xac, 0xed, 0x02, 0x4a,
0xcb, 0x2b, 0x33, 0xd0, 0xd5, 0x6c, 0x51, 0x7c, 0x26, 0x9f, 0x6e, 0x04, 0x7a, 0x54, 0x13, 0xff,
0xa6, 0x0c, 0xeb, 0x7b, 0x96, 0xb8, 0xe5, 0x38, 0xa1, 0x20, 0x77, 0x05, 0xda, 0x7e, 0xd0, 0x9f,
0xb8, 0x83, 0xc0, 0x26, 0xb2, 0x28, 0x90, 0x99, 0x7e, 0x06, 0xbe, 0x28, 0xf8, 0x71, 0x65, 0x51,
0xcc, 0x46, 0xb2, 0xc3, 0x15, 0xdf, 0xe8, 0x43, 0x38, 0xf7, 0x80, 0x7c, 0x21, 0xf7, 0xb3, 0x67,
0xbb, 0xfd, 0xbe, 0xe5, 0x98, 0x11, 0x93, 0x9a, 0x60, 0x32, 0x1f, 0xa1, 0xa8, 0x54, 0xac, 0x17,
0x96, 0x8a, 0xda, 0xcf, 0x14, 0x68, 0x27, 0x5a, 0x93, 0x7a, 0xbf, 0x11, 0xfa, 0x47, 0xa8, 0xf5,
0x8b, 0x69, 0xad, 0xe7, 0x51, 0xff, 0x73, 0xd7, 0x58, 0x4d, 0xbb, 0xc6, 0x3f, 0x15, 0x38, 0xb3,
0x67, 0xb1, 0x28, 0x28, 0x59, 0xff, 0x6b, 0x27, 0x58, 0xa0, 0xef, 0x6a, 0xb1, 0xbe, 0xbb, 0xb0,
0x99, 0xdf, 0xa8, 0x54, 0xfa, 0x69, 0xa8, 0xf1, 0x93, 0x8f, 0xee, 0x03, 0xc2, 0x81, 0xf6, 0xeb,
0x3a, 0x5c, 0xf8, 0x8c, 0x0e, 0x30, 0x8b, 0xef, 0x73, 0xee, 0xb8, 0xde, 0x21, 0x9f, 0x3a, 0x19,
0x0d, 0xe5, 0x5e, 0xc8, 0xca, 0x0b, 0x5f, 0xc8, 0x2a, 0x0b, 0x5e, 0xc8, 0xaa, 0xc7, 0x7a, 0x21,
0xab, 0x9d, 0xd8, 0x0b, 0xd9, 0x6c, 0x8f, 0x54, 0x2f, 0xec, 0x91, 0x9e, 0x64, 0xfa, 0x88, 0x15,
0xe1, 0x12, 0xdf, 0x4c, 0xbb, 0xc4, 0xc2, 0xd3, 0x59, 0x78, 0xb5, 0x9f, 0x7b, 0x58, 0x6a, 0xbc,
0xf4, 0x61, 0xa9, 0x39, 0xfb, 0xb0, 0x54, 0xfc, 0x36, 0x01, 0x73, 0xdf, 0x26, 0x2e, 0xc1, 0x9a,
0x3f, 0x75, 0x0c, 0x32, 0x88, 0x6f, 0xf9, 0x5a, 0xe1, 0xb6, 0xb3, 0xd0, 0x8c, 0xb5, 0xaf, 0xe6,
0xac, 0x3d, 0xb6, 0xd4, 0x53, 0x29, 0x4b, 0xfd, 0xef, 0x69, 0x69, 0x6e, 0xc2, 0xd6, 0xbc, 0x33,
0x91, 0xae, 0xa6, 0xc2, 0x8a, 0x31, 0xc2, 0x8e, 0x29, 0x2e, 0xdf, 0x44, 0x8f, 0x2d, 0x87, 0x3b,
0x7f, 0x00, 0xd8, 0x48, 0xea, 0x67, 0xfe, 0xd7, 0x32, 0x08, 0x7a, 0x08, 0xed, 0x3d, 0xf9, 0xfc,
0x1d, 0x5d, 0x7b, 0xa2, 0x45, 0xef, 0x08, 0x9d, 0xf3, 0xc5, 0x93, 0x21, 0x7b, 0xad, 0x84, 0x0c,
0x38, 0x97, 0x27, 0x98, 0x3c, 0x59, 0x7c, 0x7d, 0x01, 0xe5, 0x18, 0xeb, 0x65, 0x2c, 0x2e, 0x2b,
0xe8, 0x09, 0xac, 0x65, 0x2f, 0xd6, 0x51, 0xa6, 0xa0, 0x28, 0xbc, 0xeb, 0xef, 0x68, 0x8b, 0x50,
0x62, 0xf9, 0x9f, 0xf2, 0xa3, 0xce, 0xdc, 0x32, 0x23, 0x2d, 0xdb, 0x5b, 0x17, 0xdd, 0xc2, 0x77,
0xbe, 0xb6, 0x10, 0x27, 0xa6, 0xfe, 0x01, 0x34, 0xa2, 0x5b, 0xd9, 0xac, 0x9a, 0x73, 0x77, 0xb5,
0x9d, 0x76, 0x96, 0xde, 0xd0, 0xd7, 0x4a, 0xe8, 0xa3, 0x70, 0xf1, 0x2e, 0xa5, 0x05, 0x8b, 0x53,
0x77, 0x91, 0x9d, 0x37, 0x0a, 0xee, 0xff, 0xb4, 0x12, 0xfa, 0x36, 0xb4, 0xf8, 0xd7, 0xa1, 0x7c,
0x78, 0xde, 0xec, 0x86, 0xbf, 0x73, 0xe8, 0x46, 0xbf, 0x73, 0xe8, 0xde, 0x9e, 0x50, 0x36, 0xed,
0x14, 0x5c, 0xd0, 0x49, 0x02, 0x4f, 0xe1, 0xd4, 0x1e, 0x61, 0x49, 0x3f, 0x8d, 0x2e, 0x1e, 0xeb,
0xd6, 0xa1, 0xa3, 0xe5, 0xd1, 0x66, 0x5b, 0x72, 0xad, 0x84, 0x7e, 0xa9, 0xc0, 0x1b, 0x7b, 0x84,
0xe5, 0x3b, 0x54, 0xf4, 0x6e, 0x31, 0x93, 0x39, 0x9d, 0x6c, 0xe7, 0xc1, 0xb2, 0x7e, 0x97, 0x25,
0xab, 0x95, 0xd0, 0xaf, 0x14, 0x38, 0x9b, 0x12, 0x2c, 0xdd, 0x72, 0xa2, 0x6b, 0x8b, 0x85, 0x2b,
0x68, 0x4f, 0x3b, 0x9f, 0x2e, 0xf9, 0x7b, 0x82, 0x14, 0x49, 0xad, 0x84, 0x0e, 0xc5, 0x99, 0x24,
0x15, 0x26, 0xba, 0x50, 0x58, 0x4a, 0xc6, 0xdc, 0xb7, 0xe6, 0x4d, 0xc7, 0xe7, 0xf0, 0x29, 0xb4,
0xf6, 0x08, 0x8b, 0xca, 0xa1, 0xac, 0xa5, 0xe5, 0xaa, 0xd0, 0xac, 0xab, 0xe6, 0x2b, 0x28, 0x61,
0x31, 0x1b, 0x21, 0xad, 0x54, 0x59, 0x90, 0xf5, 0xd5, 0xc2, 0xda, 0x28, 0x6b, 0x31, 0xc5, 0x55,
0x85, 0x56, 0x42, 0xcf, 0x60, 0xb3, 0x38, 0x1c, 0xa2, 0xb7, 0x8f, 0x9d, 0xc6, 0x3a, 0x57, 0x8e,
0x83, 0x1a, 0xb1, 0xfc, 0x78, 0xf7, 0x2f, 0x2f, 0xb6, 0x94, 0xbf, 0xbe, 0xd8, 0x52, 0xfe, 0xf1,
0x62, 0x4b, 0xf9, 0xfe, 0xf5, 0x97, 0xfc, 0xee, 0x28, 0xf5, 0x53, 0x26, 0x4c, 0x2d, 0xc3, 0xb6,
0x88, 0xc3, 0xfa, 0x75, 0xe1, 0x6f, 0xd7, 0xff, 0x1d, 0x00, 0x00, 0xff, 0xff, 0x49, 0x49, 0x8b,
0xf4, 0xe9, 0x24, 0x00, 0x00,
// 2298 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x5a, 0x5f, 0x73, 0x1b, 0x49,
0x11, 0xf7, 0xea, 0x9f, 0xa5, 0x96, 0x63, 0xcb, 0x93, 0xc4, 0xd9, 0xe8, 0x12, 0x97, 0x6f, 0x21,
0xa9, 0x5c, 0x72, 0x27, 0x55, 0x9c, 0xba, 0x0b, 0xe4, 0x8e, 0xa3, 0x7c, 0xb9, 0xc4, 0xce, 0x25,
0x4e, 0xcc, 0x26, 0x07, 0x15, 0x08, 0x50, 0xa3, 0xd5, 0x68, 0xb5, 0xa7, 0xd5, 0xee, 0x64, 0x77,
0xd6, 0x87, 0x52, 0xc5, 0x13, 0x14, 0x1f, 0x81, 0x07, 0x5e, 0xf9, 0x02, 0x54, 0x51, 0x14, 0x8f,
0x3c, 0x50, 0xfc, 0x79, 0xa4, 0xf8, 0x02, 0x50, 0x79, 0xa1, 0x8a, 0x4f, 0x41, 0xcd, 0xec, 0xec,
0x5f, 0xad, 0x14, 0x1f, 0x72, 0x7c, 0x70, 0x2f, 0xf6, 0x4e, 0xcf, 0x4c, 0x77, 0x4f, 0x4f, 0x77,
0xcf, 0xaf, 0x67, 0x04, 0x97, 0x3d, 0x42, 0x5d, 0x9f, 0x78, 0x87, 0xc4, 0xeb, 0x8a, 0x4f, 0x8b,
0xb9, 0xde, 0x24, 0xf5, 0xd9, 0xa1, 0x9e, 0xcb, 0x5c, 0x04, 0x09, 0xa5, 0xfd, 0xc0, 0xb4, 0xd8,
0x30, 0xe8, 0x75, 0x0c, 0x77, 0xdc, 0xc5, 0x9e, 0xe9, 0x52, 0xcf, 0xfd, 0x4c, 0x7c, 0xbc, 0x63,
0xf4, 0xbb, 0x87, 0xdb, 0x5d, 0x3a, 0x32, 0xbb, 0x98, 0x5a, 0x7e, 0x17, 0x53, 0x6a, 0x5b, 0x06,
0x66, 0x96, 0xeb, 0x74, 0x0f, 0xaf, 0x63, 0x9b, 0x0e, 0xf1, 0xf5, 0xae, 0x49, 0x1c, 0xe2, 0x61,
0x46, 0xfa, 0x21, 0xe7, 0xf6, 0x1b, 0xa6, 0xeb, 0x9a, 0x36, 0xe9, 0x8a, 0x56, 0x2f, 0x18, 0x74,
0xc9, 0x98, 0x32, 0x29, 0x56, 0xfb, 0xf7, 0x0a, 0xac, 0xed, 0x63, 0xc7, 0x1a, 0x10, 0x9f, 0xe9,
0xe4, 0x79, 0x40, 0x7c, 0x86, 0x9e, 0x41, 0x85, 0x2b, 0xa3, 0x2a, 0x5b, 0xca, 0x95, 0xe6, 0xf6,
0x5e, 0x27, 0xd1, 0xa6, 0x13, 0x69, 0x23, 0x3e, 0x7e, 0x6c, 0xf4, 0x3b, 0x87, 0xdb, 0x1d, 0x3a,
0x32, 0x3b, 0x5c, 0x9b, 0x4e, 0x4a, 0x9b, 0x4e, 0xa4, 0x4d, 0x47, 0x8f, 0x97, 0xa5, 0x0b, 0xae,
0xa8, 0x0d, 0x75, 0x8f, 0x1c, 0x5a, 0xbe, 0xe5, 0x3a, 0x6a, 0x69, 0x4b, 0xb9, 0xd2, 0xd0, 0xe3,
0x36, 0x52, 0x61, 0xd9, 0x71, 0x6f, 0x63, 0x63, 0x48, 0xd4, 0xf2, 0x96, 0x72, 0xa5, 0xae, 0x47,
0x4d, 0xb4, 0x05, 0x4d, 0x4c, 0xe9, 0x03, 0xdc, 0x23, 0xf6, 0x7d, 0x32, 0x51, 0x2b, 0x62, 0x62,
0x9a, 0xc4, 0xe7, 0x62, 0x4a, 0x1f, 0xe2, 0x31, 0x51, 0xab, 0xa2, 0x37, 0x6a, 0xa2, 0x0b, 0xd0,
0x70, 0xf0, 0x98, 0xf8, 0x14, 0x1b, 0x44, 0xad, 0x8b, 0xbe, 0x84, 0x80, 0x7e, 0x0a, 0xeb, 0x29,
0xc5, 0x1f, 0xbb, 0x81, 0x67, 0x10, 0x15, 0xc4, 0xd2, 0x1f, 0x2d, 0xb6, 0xf4, 0x9d, 0x3c, 0x5b,
0x7d, 0x5a, 0x12, 0xfa, 0x11, 0x54, 0xc5, 0xce, 0xab, 0xcd, 0xad, 0xf2, 0xb1, 0x5a, 0x3b, 0x64,
0x8b, 0x1c, 0x58, 0xa6, 0x76, 0x60, 0x5a, 0x8e, 0xaf, 0xae, 0x08, 0x09, 0x4f, 0x16, 0x93, 0x70,
0xdb, 0x75, 0x06, 0x96, 0xb9, 0x8f, 0x1d, 0x6c, 0x92, 0x31, 0x71, 0xd8, 0x81, 0x60, 0xae, 0x47,
0x42, 0xd0, 0x0b, 0x68, 0x8d, 0x02, 0x9f, 0xb9, 0x63, 0xeb, 0x05, 0x79, 0x44, 0xf9, 0x5c, 0x5f,
0x3d, 0x25, 0xac, 0xf9, 0x70, 0x31, 0xc1, 0xf7, 0x73, 0x5c, 0xf5, 0x29, 0x39, 0xdc, 0x49, 0x46,
0x41, 0x8f, 0x7c, 0x97, 0x78, 0xc2, 0xbb, 0x56, 0x43, 0x27, 0x49, 0x91, 0x42, 0x37, 0xb2, 0x64,
0xcb, 0x57, 0xd7, 0xb6, 0xca, 0xa1, 0x1b, 0xc5, 0x24, 0x74, 0x05, 0xd6, 0x0e, 0x89, 0x67, 0x0d,
0x26, 0x8f, 0x2d, 0xd3, 0xc1, 0x2c, 0xf0, 0x88, 0xda, 0x12, 0xae, 0x98, 0x27, 0xa3, 0x31, 0x9c,
0x1a, 0x12, 0x7b, 0xcc, 0x4d, 0x7e, 0xdb, 0x23, 0x7d, 0x5f, 0x5d, 0x17, 0xf6, 0xdd, 0x5d, 0x7c,
0x07, 0x05, 0x3b, 0x3d, 0xcb, 0x9d, 0x2b, 0xe6, 0xb8, 0xba, 0x8c, 0x94, 0x30, 0x46, 0x50, 0xa8,
0x58, 0x8e, 0x8c, 0x2e, 0xc3, 0x2a, 0xf3, 0xb0, 0x31, 0xb2, 0x1c, 0x73, 0x9f, 0xb0, 0xa1, 0xdb,
0x57, 0x4f, 0x0b, 0x4b, 0xe4, 0xa8, 0xc8, 0x00, 0x44, 0x1c, 0xdc, 0xb3, 0x49, 0x3f, 0xf4, 0xc5,
0x27, 0x13, 0x4a, 0x7c, 0xf5, 0x8c, 0x58, 0xc5, 0x8d, 0x4e, 0x2a, 0x43, 0xe5, 0x12, 0x44, 0xe7,
0xce, 0xd4, 0xac, 0x3b, 0x0e, 0xf3, 0x26, 0x7a, 0x01, 0x3b, 0x34, 0x82, 0x26, 0x5f, 0x47, 0xe4,
0x0a, 0x67, 0x85, 0x2b, 0xdc, 0x5b, 0xcc, 0x46, 0x7b, 0x09, 0x43, 0x3d, 0xcd, 0x1d, 0x75, 0x00,
0x0d, 0xb1, 0xbf, 0x1f, 0xd8, 0xcc, 0xa2, 0x36, 0x09, 0xd5, 0xf0, 0xd5, 0x0d, 0x61, 0xa6, 0x82,
0x1e, 0x74, 0x1f, 0xc0, 0x23, 0x83, 0x68, 0xdc, 0x39, 0xb1, 0xf2, 0x6b, 0xf3, 0x56, 0xae, 0xc7,
0xa3, 0xc3, 0x15, 0xa7, 0xa6, 0x73, 0xe1, 0x7c, 0x19, 0xc4, 0x60, 0x32, 0xda, 0x45, 0x58, 0xab,
0xc2, 0xc5, 0x0a, 0x7a, 0xb8, 0x2f, 0x4a, 0xaa, 0x48, 0x5a, 0xe7, 0x43, 0x6f, 0x4d, 0x91, 0xda,
0x77, 0xe0, 0xdc, 0x0c, 0x53, 0xa3, 0x16, 0x94, 0x47, 0x64, 0x22, 0x52, 0x74, 0x43, 0xe7, 0x9f,
0xe8, 0x0c, 0x54, 0x0f, 0xb1, 0x1d, 0x10, 0x91, 0x54, 0xeb, 0x7a, 0xd8, 0xb8, 0x55, 0xfa, 0x86,
0xd2, 0xfe, 0x85, 0x02, 0x6b, 0x39, 0xc5, 0x0b, 0xe6, 0xff, 0x30, 0x3d, 0xff, 0x18, 0xdc, 0x78,
0xf0, 0x04, 0x7b, 0x26, 0x61, 0x29, 0x45, 0xb4, 0xbf, 0x2b, 0xa0, 0xe6, 0x2c, 0xfa, 0x3d, 0x8b,
0x0d, 0xef, 0x5a, 0x36, 0xf1, 0xd1, 0x4d, 0x58, 0xf6, 0x42, 0x9a, 0x3c, 0x78, 0xde, 0x98, 0xb3,
0x11, 0x7b, 0x4b, 0x7a, 0x34, 0x1a, 0x7d, 0x08, 0xf5, 0x31, 0x61, 0xb8, 0x8f, 0x19, 0x96, 0xba,
0x6f, 0x15, 0xcd, 0xe4, 0x52, 0xf6, 0xe5, 0xb8, 0xbd, 0x25, 0x3d, 0x9e, 0x83, 0xde, 0x85, 0xaa,
0x31, 0x0c, 0x9c, 0x91, 0x38, 0x72, 0x9a, 0xdb, 0x17, 0x67, 0x4d, 0xbe, 0xcd, 0x07, 0xed, 0x2d,
0xe9, 0xe1, 0xe8, 0x8f, 0x6a, 0x50, 0xa1, 0xd8, 0x63, 0xda, 0x5d, 0x38, 0x53, 0x24, 0x82, 0x9f,
0x73, 0xc6, 0x90, 0x18, 0x23, 0x3f, 0x18, 0x4b, 0x33, 0xc7, 0x6d, 0x84, 0xa0, 0xe2, 0x5b, 0x2f,
0x42, 0x53, 0x97, 0x75, 0xf1, 0xad, 0xbd, 0x05, 0xeb, 0x53, 0xd2, 0xf8, 0xa6, 0x86, 0xba, 0x71,
0x0e, 0x2b, 0x52, 0xb4, 0x16, 0xc0, 0xd9, 0x27, 0xc2, 0x16, 0x71, 0xb2, 0x3f, 0x89, 0x93, 0x5b,
0xdb, 0x83, 0x8d, 0xbc, 0x58, 0x9f, 0xba, 0x8e, 0x4f, 0xb8, 0xeb, 0x8b, 0xec, 0x68, 0x91, 0x7e,
0xd2, 0x2b, 0xb4, 0xa8, 0xeb, 0x05, 0x3d, 0xda, 0xaf, 0x4b, 0xb0, 0xa1, 0x13, 0xdf, 0xb5, 0x0f,
0x49, 0x94, 0xba, 0x4e, 0x06, 0x7c, 0xfc, 0x00, 0xca, 0x98, 0x52, 0xe9, 0x26, 0xf7, 0x8e, 0xed,
0x78, 0xd7, 0x39, 0x57, 0xf4, 0x36, 0xac, 0xe3, 0x71, 0xcf, 0x32, 0x03, 0x37, 0xf0, 0xa3, 0x65,
0x09, 0xa7, 0x6a, 0xe8, 0xd3, 0x1d, 0x3c, 0xfc, 0x7d, 0x11, 0x91, 0xf7, 0x9c, 0x3e, 0xf9, 0x89,
0x40, 0x34, 0x65, 0x3d, 0x4d, 0xd2, 0x0c, 0x38, 0x37, 0x65, 0x24, 0x69, 0xf0, 0x34, 0x88, 0x52,
0x72, 0x20, 0xaa, 0x50, 0x8d, 0xd2, 0x0c, 0x35, 0xb4, 0x3f, 0x2b, 0xd0, 0x4a, 0x82, 0x4b, 0xb2,
0xbf, 0x00, 0x8d, 0xb1, 0xa4, 0xf9, 0xaa, 0x22, 0x32, 0x58, 0x42, 0xc8, 0xe2, 0xa9, 0x52, 0x1e,
0x4f, 0x6d, 0x40, 0x2d, 0x84, 0xbb, 0x72, 0xe9, 0xb2, 0x95, 0x51, 0xb9, 0x92, 0x53, 0x79, 0x13,
0xc0, 0x8f, 0x33, 0x9c, 0x5a, 0x13, 0xbd, 0x29, 0x0a, 0xd2, 0x60, 0x25, 0x3c, 0x7d, 0x75, 0xe2,
0x07, 0x36, 0x53, 0x97, 0xc5, 0x88, 0x0c, 0x4d, 0x73, 0x61, 0xed, 0x81, 0xc5, 0xd7, 0x30, 0xf0,
0x4f, 0x26, 0x1c, 0xde, 0x83, 0x0a, 0x17, 0xc6, 0x17, 0xd6, 0xf3, 0xb0, 0x63, 0x0c, 0x49, 0x64,
0xab, 0xb8, 0xcd, 0x03, 0x9d, 0x61, 0xd3, 0x57, 0x4b, 0x82, 0x2e, 0xbe, 0xb5, 0xdf, 0x97, 0x42,
0x4d, 0x77, 0x28, 0xf5, 0xbf, 0x7c, 0xc8, 0x5d, 0x0c, 0x02, 0xca, 0xd3, 0x20, 0x20, 0xa7, 0xf2,
0x17, 0x01, 0x01, 0xc7, 0x74, 0x90, 0x69, 0x01, 0x2c, 0xef, 0x50, 0xca, 0x15, 0x41, 0xd7, 0xa1,
0x82, 0x29, 0x0d, 0x0d, 0x9e, 0xcb, 0xd9, 0x72, 0x08, 0xff, 0x2f, 0x55, 0x12, 0x43, 0xdb, 0x37,
0xa1, 0x11, 0x93, 0x5e, 0x25, 0xb6, 0x91, 0x16, 0xbb, 0x05, 0x10, 0xa2, 0xdc, 0x7b, 0xce, 0xc0,
0xe5, 0x5b, 0xca, 0x9d, 0x5d, 0x4e, 0x15, 0xdf, 0xda, 0xad, 0x68, 0x84, 0xd0, 0xed, 0x6d, 0xa8,
0x5a, 0x8c, 0x8c, 0x23, 0xe5, 0x36, 0xd2, 0xca, 0x25, 0x8c, 0xf4, 0x70, 0x90, 0xf6, 0x97, 0x3a,
0x9c, 0xe7, 0x3b, 0xf6, 0x58, 0x84, 0xc9, 0x0e, 0xa5, 0x1f, 0x13, 0x86, 0x2d, 0xdb, 0xff, 0x4e,
0x40, 0xbc, 0xc9, 0x6b, 0x76, 0x0c, 0x13, 0x6a, 0x61, 0x94, 0xc9, 0x8c, 0x78, 0xec, 0x05, 0x8f,
0x64, 0x9f, 0x54, 0x39, 0xe5, 0xd7, 0x53, 0xe5, 0x14, 0x55, 0x1d, 0x95, 0x13, 0xaa, 0x3a, 0x66,
0x17, 0x9e, 0xa9, 0x72, 0xb6, 0x96, 0x2d, 0x67, 0x0b, 0xc0, 0xfc, 0xf2, 0x51, 0xc1, 0x7c, 0xbd,
0x10, 0xcc, 0x8f, 0x0b, 0xe3, 0xb8, 0x21, 0xcc, 0xfd, 0xad, 0xb4, 0x07, 0xce, 0xf4, 0xb5, 0x45,
0x60, 0x3d, 0xbc, 0x56, 0x58, 0xff, 0x69, 0x06, 0xa6, 0x87, 0x85, 0xf2, 0xbb, 0x47, 0x5b, 0xd3,
0x1c, 0xc0, 0xfe, 0x95, 0x83, 0xd7, 0x3f, 0x17, 0xa8, 0x8a, 0xba, 0x89, 0x0d, 0xe2, 0x03, 0x9d,
0x9f, 0x43, 0xfc, 0x68, 0x95, 0x49, 0x8b, 0x7f, 0xa3, 0x6b, 0x50, 0xe1, 0x46, 0x96, 0xb0, 0xf7,
0x5c, 0xda, 0x9e, 0x7c, 0x27, 0x76, 0x28, 0x7d, 0x4c, 0x89, 0xa1, 0x8b, 0x41, 0xe8, 0x16, 0x34,
0x62, 0xc7, 0x97, 0x91, 0x75, 0x21, 0x3d, 0x23, 0x8e, 0x93, 0x68, 0x5a, 0x32, 0x9c, 0xcf, 0xed,
0x5b, 0x1e, 0x31, 0x04, 0x28, 0xac, 0x4e, 0xcf, 0xfd, 0x38, 0xea, 0x8c, 0xe7, 0xc6, 0xc3, 0xd1,
0x75, 0xa8, 0x85, 0x37, 0x0b, 0x22, 0x82, 0x9a, 0xdb, 0xe7, 0xa7, 0x93, 0x69, 0x34, 0x4b, 0x0e,
0xd4, 0xfe, 0xa4, 0xc0, 0x9b, 0x89, 0x43, 0x44, 0xd1, 0x14, 0xe1, 0xf2, 0x2f, 0xff, 0xc4, 0xbd,
0x0c, 0xab, 0xa2, 0x10, 0x48, 0x2e, 0x18, 0xc2, 0xbb, 0xae, 0x1c, 0x55, 0xfb, 0x9d, 0x02, 0x97,
0xa6, 0xd7, 0x71, 0x7b, 0x88, 0x3d, 0x16, 0x6f, 0xef, 0x49, 0xac, 0x25, 0x3a, 0xf0, 0x4a, 0xc9,
0x81, 0x97, 0x59, 0x5f, 0x39, 0xbb, 0x3e, 0xed, 0x0f, 0x25, 0x68, 0xa6, 0x1c, 0xa8, 0xe8, 0xc0,
0xe4, 0x80, 0x4f, 0xf8, 0xad, 0x28, 0xfd, 0xc4, 0xa1, 0xd0, 0xd0, 0x53, 0x14, 0x34, 0x02, 0xa0,
0xd8, 0xc3, 0x63, 0xc2, 0x88, 0xc7, 0x33, 0x39, 0x8f, 0xf8, 0xfb, 0x8b, 0x67, 0x97, 0x83, 0x88,
0xa7, 0x9e, 0x62, 0xcf, 0x11, 0xab, 0x10, 0xed, 0xcb, 0xfc, 0x2d, 0x5b, 0xe8, 0x73, 0x58, 0x1d,
0x58, 0x36, 0x39, 0x48, 0x14, 0xa9, 0x09, 0x45, 0x1e, 0x2d, 0xae, 0xc8, 0xdd, 0x34, 0x5f, 0x3d,
0x27, 0x46, 0xbb, 0x0a, 0xad, 0x7c, 0x3c, 0x71, 0x25, 0xad, 0x31, 0x36, 0x63, 0x6b, 0xc9, 0x96,
0x86, 0xa0, 0x95, 0x8f, 0x1f, 0xed, 0x1f, 0x25, 0x38, 0x1b, 0xb3, 0xdb, 0x71, 0x1c, 0x37, 0x70,
0x0c, 0x71, 0x59, 0x57, 0xb8, 0x17, 0x67, 0xa0, 0xca, 0x2c, 0x66, 0xc7, 0xc0, 0x47, 0x34, 0xf8,
0xd9, 0xc5, 0x5c, 0xd7, 0x66, 0x16, 0x95, 0x1b, 0x1c, 0x35, 0xc3, 0xbd, 0x7f, 0x1e, 0x58, 0x1e,
0xe9, 0x8b, 0x4c, 0x50, 0xd7, 0xe3, 0x36, 0xef, 0xe3, 0xa8, 0x46, 0xc0, 0xf8, 0xd0, 0x98, 0x71,
0x5b, 0xf8, 0xbd, 0x6b, 0xdb, 0xc4, 0xe0, 0xe6, 0x48, 0x01, 0xfd, 0x1c, 0x55, 0x14, 0x10, 0xcc,
0xb3, 0x1c, 0x53, 0xc2, 0x7c, 0xd9, 0xe2, 0x7a, 0x62, 0xcf, 0xc3, 0x13, 0xb5, 0x2e, 0x0c, 0x10,
0x36, 0xd0, 0x07, 0x50, 0x1e, 0x63, 0x2a, 0x0f, 0xba, 0xab, 0x99, 0xec, 0x50, 0x64, 0x81, 0xce,
0x3e, 0xa6, 0xe1, 0x49, 0xc0, 0xa7, 0xb5, 0xdf, 0x83, 0x7a, 0x44, 0xf8, 0x42, 0x90, 0xf0, 0x33,
0x38, 0x95, 0x49, 0x3e, 0xe8, 0x29, 0x6c, 0x24, 0x1e, 0x95, 0x16, 0x28, 0x41, 0xe0, 0x9b, 0xaf,
0xd4, 0x4c, 0x9f, 0xc1, 0x40, 0x7b, 0x0e, 0xeb, 0xdc, 0x65, 0x44, 0xe0, 0x9f, 0x50, 0x69, 0xf3,
0x3e, 0x34, 0x62, 0x91, 0x85, 0x3e, 0xd3, 0x86, 0xfa, 0x61, 0x74, 0x89, 0x1a, 0xd6, 0x36, 0x71,
0x5b, 0xdb, 0x01, 0x94, 0xd6, 0x57, 0x9e, 0x40, 0xd7, 0xb2, 0xa0, 0xf8, 0x6c, 0xfe, 0xb8, 0x11,
0xc3, 0x23, 0x4c, 0xfc, 0xdb, 0x12, 0xac, 0xed, 0x5a, 0xe2, 0x1e, 0xe4, 0x84, 0x92, 0xdc, 0x55,
0x68, 0xf9, 0x41, 0x6f, 0xec, 0xf6, 0x03, 0x9b, 0x48, 0x50, 0x20, 0x4f, 0xfa, 0x29, 0xfa, 0xbc,
0xe4, 0xc7, 0x8d, 0x45, 0x31, 0x1b, 0xca, 0x0a, 0x57, 0x7c, 0xa3, 0x0f, 0xe0, 0xfc, 0x43, 0xf2,
0xb9, 0x5c, 0xcf, 0xae, 0xed, 0xf6, 0x7a, 0x96, 0x63, 0x46, 0x42, 0xaa, 0x42, 0xc8, 0xec, 0x01,
0x45, 0x50, 0xb1, 0x56, 0x08, 0x15, 0xb5, 0x9f, 0x29, 0xd0, 0x4a, 0xac, 0x26, 0xed, 0x7e, 0x33,
0x8c, 0x8f, 0xd0, 0xea, 0x97, 0xd2, 0x56, 0xcf, 0x0f, 0xfd, 0xef, 0x43, 0x63, 0x25, 0x1d, 0x1a,
0xff, 0x52, 0xe0, 0xec, 0xae, 0xc5, 0xa2, 0xa4, 0x64, 0xfd, 0xbf, 0xed, 0x60, 0x81, 0xbd, 0x2b,
0xc5, 0xf6, 0xee, 0xc0, 0x46, 0x7e, 0xa1, 0xd2, 0xe8, 0x67, 0xa0, 0xca, 0x77, 0x3e, 0xba, 0x0f,
0x08, 0x1b, 0xda, 0x6f, 0x6a, 0x70, 0xf1, 0x53, 0xda, 0xc7, 0x2c, 0xbe, 0xcf, 0xb9, 0xeb, 0x7a,
0x07, 0xbc, 0xeb, 0x64, 0x2c, 0x94, 0x7b, 0x43, 0x2b, 0xcd, 0x7d, 0x43, 0x2b, 0xcf, 0x79, 0x43,
0xab, 0x1c, 0xe9, 0x0d, 0xad, 0x7a, 0x62, 0x6f, 0x68, 0xd3, 0x35, 0x52, 0xad, 0xb0, 0x46, 0x7a,
0x9a, 0xa9, 0x23, 0x96, 0x45, 0x48, 0x7c, 0x33, 0x1d, 0x12, 0x73, 0x77, 0x67, 0xee, 0xe5, 0x7f,
0xee, 0xe9, 0xa9, 0xfe, 0xca, 0xa7, 0xa7, 0xc6, 0xf4, 0xd3, 0x53, 0xf1, 0xeb, 0x05, 0xcc, 0x7c,
0xbd, 0xb8, 0x0c, 0xab, 0xfe, 0xc4, 0x31, 0x48, 0x3f, 0xbe, 0xe5, 0x6b, 0x86, 0xcb, 0xce, 0x52,
0x33, 0xde, 0xbe, 0x92, 0xf3, 0xf6, 0xd8, 0x53, 0x4f, 0xa5, 0x3c, 0xf5, 0x7f, 0xa7, 0xa4, 0xb9,
0x05, 0x9b, 0xb3, 0xf6, 0x44, 0x86, 0x9a, 0x0a, 0xcb, 0xc6, 0x10, 0x3b, 0xa6, 0xb8, 0x7c, 0x13,
0x35, 0xb6, 0x6c, 0x6e, 0xff, 0x11, 0x60, 0x3d, 0xc1, 0xcf, 0xfc, 0xaf, 0x65, 0x10, 0xf4, 0x08,
0x5a, 0xbb, 0xf2, 0x81, 0x3c, 0xba, 0xf6, 0x44, 0xf3, 0x5e, 0x1a, 0xda, 0x17, 0x8a, 0x3b, 0x43,
0xf1, 0xda, 0x12, 0x32, 0xe0, 0x7c, 0x9e, 0x61, 0xf2, 0xa8, 0xf1, 0xf5, 0x39, 0x9c, 0xe3, 0x51,
0xaf, 0x12, 0x71, 0x45, 0x41, 0x4f, 0x61, 0x35, 0x7b, 0xf5, 0x8e, 0x32, 0x80, 0xa2, 0xf0, 0x35,
0xa0, 0xad, 0xcd, 0x1b, 0x12, 0xeb, 0xff, 0x8c, 0x6f, 0x75, 0xe6, 0x96, 0x19, 0x69, 0xd9, 0xda,
0xba, 0xe8, 0x9e, 0xbe, 0xfd, 0xb5, 0xb9, 0x63, 0x62, 0xee, 0xef, 0x43, 0x3d, 0xba, 0x95, 0xcd,
0x9a, 0x39, 0x77, 0x57, 0xdb, 0x6e, 0x65, 0xf9, 0x0d, 0x7c, 0x6d, 0x09, 0x7d, 0x18, 0x4e, 0xde,
0xa1, 0xb4, 0x60, 0x72, 0xea, 0x2e, 0xb2, 0x7d, 0xba, 0xe0, 0xfe, 0x4f, 0x5b, 0x42, 0xdf, 0x86,
0x26, 0xff, 0x3a, 0x90, 0x4f, 0xd3, 0x1b, 0x9d, 0xf0, 0x97, 0x10, 0x9d, 0xe8, 0x97, 0x10, 0x9d,
0x3b, 0x63, 0xca, 0x26, 0xed, 0x82, 0x0b, 0x3a, 0xc9, 0xe0, 0x19, 0x9c, 0xda, 0x25, 0x2c, 0xa9,
0xa7, 0xd1, 0xa5, 0x23, 0xdd, 0x3a, 0xb4, 0xb5, 0xfc, 0xb0, 0xe9, 0x92, 0x5c, 0x5b, 0x42, 0xbf,
0x54, 0xe0, 0xf4, 0x2e, 0x61, 0xf9, 0x0a, 0x15, 0xbd, 0x53, 0x2c, 0x64, 0x46, 0x25, 0xdb, 0x7e,
0xb8, 0x68, 0xdc, 0x65, 0xd9, 0x6a, 0x4b, 0xe8, 0x57, 0x0a, 0x9c, 0x4b, 0x29, 0x96, 0x2e, 0x39,
0xd1, 0xf5, 0xf9, 0xca, 0x15, 0x94, 0xa7, 0xed, 0x4f, 0x16, 0xfc, 0xc5, 0x41, 0x8a, 0xa5, 0xb6,
0x84, 0x0e, 0xc4, 0x9e, 0x24, 0x08, 0x13, 0x5d, 0x2c, 0x84, 0x92, 0xb1, 0xf4, 0xcd, 0x59, 0xdd,
0xf1, 0x3e, 0x7c, 0x02, 0xcd, 0x5d, 0xc2, 0x22, 0x38, 0x94, 0xf5, 0xb4, 0x1c, 0x0a, 0xcd, 0x86,
0x6a, 0x1e, 0x41, 0x09, 0x8f, 0x59, 0x0f, 0x79, 0xa5, 0x60, 0x41, 0x36, 0x56, 0x0b, 0xb1, 0x51,
0xd6, 0x63, 0x8a, 0x51, 0x85, 0xb6, 0x84, 0x9e, 0xc3, 0x46, 0x71, 0x3a, 0x44, 0x6f, 0x1d, 0xf9,
0x18, 0x6b, 0x5f, 0x3d, 0xca, 0xd0, 0x48, 0xe4, 0x47, 0x3b, 0x7f, 0x7d, 0xb9, 0xa9, 0xfc, 0xed,
0xe5, 0xa6, 0xf2, 0xcf, 0x97, 0x9b, 0xca, 0xf7, 0x6f, 0xbc, 0xe2, 0x97, 0x49, 0xa9, 0x1f, 0x3b,
0x61, 0x6a, 0x19, 0xb6, 0x45, 0x1c, 0xd6, 0xab, 0x89, 0x78, 0xbb, 0xf1, 0x9f, 0x00, 0x00, 0x00,
0xff, 0xff, 0xe7, 0xa3, 0xda, 0xab, 0x0b, 0x25, 0x00, 0x00,
}
// Reference imports to suppress errors if they are not otherwise used.
@@ -3719,6 +3728,11 @@ func (m *ResolveRevisionRequest) MarshalToSizedBuffer(dAtA []byte) (int, error)
i -= len(m.XXX_unrecognized)
copy(dAtA[i:], m.XXX_unrecognized)
}
if m.SourceIndex != 0 {
i = encodeVarintRepository(dAtA, i, uint64(m.SourceIndex))
i--
dAtA[i] = 0x20
}
if len(m.AmbiguousRevision) > 0 {
i -= len(m.AmbiguousRevision)
copy(dAtA[i:], m.AmbiguousRevision)
@@ -5601,6 +5615,9 @@ func (m *ResolveRevisionRequest) Size() (n int) {
if l > 0 {
n += 1 + l + sovRepository(uint64(l))
}
if m.SourceIndex != 0 {
n += 1 + sovRepository(uint64(m.SourceIndex))
}
if m.XXX_unrecognized != nil {
n += len(m.XXX_unrecognized)
}
@@ -7871,6 +7888,25 @@ func (m *ResolveRevisionRequest) Unmarshal(dAtA []byte) error {
}
m.AmbiguousRevision = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 4:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field SourceIndex", wireType)
}
m.SourceIndex = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowRepository
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.SourceIndex |= int64(b&0x7F) << shift
if b < 0x80 {
break
}
}
default:
iNdEx = preIndex
skippy, err := skipRepository(dAtA[iNdEx:])

View File

@@ -354,6 +354,11 @@ func (c *Cache) GetManifests(revision string, appSrc *appv1.ApplicationSource, s
// The expected hash matches the actual hash, so remove the hash from the returned value
res.CacheEntryHash = ""
if res.ManifestResponse != nil {
// cached manifest response might be reused across different revisions, so we need to assume that the revision is the one we are looking for
res.ManifestResponse.Revision = revision
}
return nil
}

View File

@@ -124,11 +124,18 @@ func TestCache_GetManifests(t *testing.T) {
assert.Equal(t, ErrCacheMiss, err)
})
t.Run("expect cache hit", func(t *testing.T) {
err = cache.GetManifests("my-revision", &ApplicationSource{}, q.RefSources, q, "my-namespace", "", "my-app-label-key", "my-app-label-value", value, nil)
err = cache.SetManifests(
"my-revision1", &ApplicationSource{}, q.RefSources, q, "my-namespace", "", "my-app-label-key", "my-app-label-value",
&CachedManifestResponse{ManifestResponse: &apiclient.ManifestResponse{SourceType: "my-source-type", Revision: "my-revision2"}}, nil)
assert.NoError(t, err)
assert.Equal(t, &CachedManifestResponse{ManifestResponse: &apiclient.ManifestResponse{SourceType: "my-source-type"}}, value)
err = cache.GetManifests("my-revision1", &ApplicationSource{}, q.RefSources, q, "my-namespace", "", "my-app-label-key", "my-app-label-value", value, nil)
assert.NoError(t, err)
assert.Equal(t, "my-source-type", value.ManifestResponse.SourceType)
assert.Equal(t, "my-revision1", value.ManifestResponse.Revision)
})
mockCache.AssertCacheCalledTimes(t, &mocks.CacheCallCounts{ExternalSets: 1, ExternalGets: 8})
mockCache.AssertCacheCalledTimes(t, &mocks.CacheCallCounts{ExternalSets: 2, ExternalGets: 8})
}
func TestCache_GetAppDetails(t *testing.T) {

View File

@@ -2512,7 +2512,7 @@ func (s *Service) ResolveRevision(ctx context.Context, q *apiclient.ResolveRevis
app := q.App
ambiguousRevision := q.AmbiguousRevision
var revision string
var source = app.Spec.GetSource()
var source = app.Spec.GetSourcePtrByIndex(int(q.SourceIndex))
if source.IsHelm() {
_, revision, err := s.newHelmClientResolveRevision(repo, ambiguousRevision, source.Chart, true)

View File

@@ -73,6 +73,7 @@ message ResolveRevisionRequest {
github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.Repository repo = 1;
github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.Application app = 2;
string ambiguousRevision = 3;
int64 sourceIndex = 4;
}
// ResolveRevisionResponse

View File

@@ -302,7 +302,7 @@ func TestGenerateManifests_K8SAPIResetCache(t *testing.T) {
ProjectSourceRepos: []string{"*"},
}
cachedFakeResponse := &apiclient.ManifestResponse{Manifests: []string{"Fake"}}
cachedFakeResponse := &apiclient.ManifestResponse{Manifests: []string{"Fake"}, Revision: mock.Anything}
err := service.cache.SetManifests(mock.Anything, &src, q.RefSources, &q, "", "", "", "", &cache.CachedManifestResponse{ManifestResponse: cachedFakeResponse}, nil)
assert.NoError(t, err)

View File

@@ -150,7 +150,7 @@ func NewServer(
//
// If the user does provide a "project," we can respond more specifically. If the user does not have access to the given
// app name in the given project, we return "permission denied." If the app exists, but the project is different from
func (s *Server) getAppEnforceRBAC(ctx context.Context, action, project, namespace, name string, getApp func() (*appv1.Application, error)) (*appv1.Application, error) {
func (s *Server) getAppEnforceRBAC(ctx context.Context, action, project, namespace, name string, getApp func() (*appv1.Application, error)) (*appv1.Application, *appv1.AppProject, error) {
user := session.Username(ctx)
if user == "" {
user = "Unknown user"
@@ -172,7 +172,7 @@ func (s *Server) getAppEnforceRBAC(ctx context.Context, action, project, namespa
// but the app is in a different project" response. We don't want the user inferring the existence of the
// app from response time.
_, _ = getApp()
return nil, permissionDeniedErr
return nil, nil, permissionDeniedErr
}
}
a, err := getApp()
@@ -180,15 +180,15 @@ func (s *Server) getAppEnforceRBAC(ctx context.Context, action, project, namespa
if apierr.IsNotFound(err) {
if project != "" {
// We know that the user was allowed to get the Application, but the Application does not exist. Return 404.
return nil, status.Errorf(codes.NotFound, apierr.NewNotFound(schema.GroupResource{Group: "argoproj.io", Resource: "applications"}, name).Error())
return nil, nil, status.Errorf(codes.NotFound, apierr.NewNotFound(schema.GroupResource{Group: "argoproj.io", Resource: "applications"}, name).Error())
}
// We don't know if the user was allowed to get the Application, and we don't want to leak information about
// the Application's existence. Return 403.
logCtx.Warn("application does not exist")
return nil, permissionDeniedErr
return nil, nil, permissionDeniedErr
}
logCtx.Errorf("failed to get application: %s", err)
return nil, permissionDeniedErr
return nil, nil, permissionDeniedErr
}
// Even if we performed an initial RBAC check (because the request was fully parameterized), we still need to
// perform a second RBAC check to ensure that the user has access to the actual Application's project (not just the
@@ -202,11 +202,11 @@ func (s *Server) getAppEnforceRBAC(ctx context.Context, action, project, namespa
// The user specified a project. We would have returned a 404 if the user had access to the app, but the app
// did not exist. So we have to return a 404 when the app does exist, but the user does not have access.
// Otherwise, they could infer that the app exists based on the error code.
return nil, status.Errorf(codes.NotFound, apierr.NewNotFound(schema.GroupResource{Group: "argoproj.io", Resource: "applications"}, name).Error())
return nil, nil, status.Errorf(codes.NotFound, apierr.NewNotFound(schema.GroupResource{Group: "argoproj.io", Resource: "applications"}, name).Error())
}
// The user didn't specify a project. We always return permission denied for both lack of access and lack of
// existence.
return nil, permissionDeniedErr
return nil, nil, permissionDeniedErr
}
effectiveProject := "default"
if a.Spec.Project != "" {
@@ -219,15 +219,20 @@ func (s *Server) getAppEnforceRBAC(ctx context.Context, action, project, namespa
}).Warnf("user tried to %s application in project %s, but the application is in project %s", action, project, effectiveProject)
// The user has access to the app, but the app is in a different project. Return 404, meaning "app doesn't
// exist in that project".
return nil, status.Errorf(codes.NotFound, apierr.NewNotFound(schema.GroupResource{Group: "argoproj.io", Resource: "applications"}, name).Error())
return nil, nil, status.Errorf(codes.NotFound, apierr.NewNotFound(schema.GroupResource{Group: "argoproj.io", Resource: "applications"}, name).Error())
}
return a, nil
// Get the app's associated project, and make sure all project restrictions are enforced.
proj, err := s.getAppProject(ctx, a, logCtx)
if err != nil {
return a, nil, err
}
return a, proj, nil
}
// getApplicationEnforceRBACInformer uses an informer to get an Application. If the app does not exist, permission is
// denied, or any other error occurs when getting the app, we return a permission denied error to obscure any sensitive
// information.
func (s *Server) getApplicationEnforceRBACInformer(ctx context.Context, action, project, namespace, name string) (*appv1.Application, error) {
func (s *Server) getApplicationEnforceRBACInformer(ctx context.Context, action, project, namespace, name string) (*appv1.Application, *appv1.AppProject, error) {
namespaceOrDefault := s.appNamespaceOrDefault(namespace)
return s.getAppEnforceRBAC(ctx, action, project, namespaceOrDefault, name, func() (*appv1.Application, error) {
return s.appLister.Applications(namespaceOrDefault).Get(name)
@@ -237,7 +242,7 @@ func (s *Server) getApplicationEnforceRBACInformer(ctx context.Context, action,
// getApplicationEnforceRBACClient uses a client to get an Application. If the app does not exist, permission is denied,
// or any other error occurs when getting the app, we return a permission denied error to obscure any sensitive
// information.
func (s *Server) getApplicationEnforceRBACClient(ctx context.Context, action, project, namespace, name, resourceVersion string) (*appv1.Application, error) {
func (s *Server) getApplicationEnforceRBACClient(ctx context.Context, action, project, namespace, name, resourceVersion string) (*appv1.Application, *appv1.AppProject, error) {
namespaceOrDefault := s.appNamespaceOrDefault(namespace)
return s.getAppEnforceRBAC(ctx, action, project, namespaceOrDefault, name, func() (*appv1.Application, error) {
if !s.isNamespaceEnabled(namespaceOrDefault) {
@@ -321,7 +326,13 @@ func (s *Server) Create(ctx context.Context, q *application.ApplicationCreateReq
if q.Validate != nil {
validate = *q.Validate
}
err := s.validateAndNormalizeApp(ctx, a, validate)
proj, err := s.getAppProject(ctx, a, log.WithField("application", a.Name))
if err != nil {
return nil, err
}
err = s.validateAndNormalizeApp(ctx, a, proj, validate)
if err != nil {
return nil, fmt.Errorf("error while validating and normalizing app: %w", err)
}
@@ -377,7 +388,7 @@ func (s *Server) Create(ctx context.Context, q *application.ApplicationCreateReq
return updated, nil
}
func (s *Server) queryRepoServer(ctx context.Context, a *appv1.Application, action func(
func (s *Server) queryRepoServer(ctx context.Context, proj *appv1.AppProject, action func(
client apiclient.RepoServerServiceClient,
helmRepos []*appv1.Repository,
helmCreds []*appv1.RepoCreds,
@@ -391,14 +402,6 @@ func (s *Server) queryRepoServer(ctx context.Context, a *appv1.Application, acti
}
defer ioutil.Close(closer)
proj, err := argo.GetAppProject(a, applisters.NewAppProjectLister(s.projInformer.GetIndexer()), s.ns, s.settingsMgr, s.db, ctx)
if err != nil {
if apierr.IsNotFound(err) {
return status.Errorf(codes.InvalidArgument, "application references project %s which does not exist", a.Spec.Project)
}
return fmt.Errorf("error getting application's project: %w", err)
}
helmRepos, err := s.db.ListHelmRepositories(ctx)
if err != nil {
return fmt.Errorf("error listing helm repositories: %w", err)
@@ -432,7 +435,7 @@ func (s *Server) GetManifests(ctx context.Context, q *application.ApplicationMan
if q.Name == nil || *q.Name == "" {
return nil, fmt.Errorf("invalid request: application name is missing")
}
a, err := s.getApplicationEnforceRBACInformer(ctx, rbacpolicy.ActionGet, q.GetProject(), q.GetAppNamespace(), q.GetName())
a, proj, err := s.getApplicationEnforceRBACInformer(ctx, rbacpolicy.ActionGet, q.GetProject(), q.GetAppNamespace(), q.GetName())
if err != nil {
return nil, err
}
@@ -442,7 +445,7 @@ func (s *Server) GetManifests(ctx context.Context, q *application.ApplicationMan
}
manifestInfos := make([]*apiclient.ManifestResponse, 0)
err = s.queryRepoServer(ctx, a, func(
err = s.queryRepoServer(ctx, proj, func(
client apiclient.RepoServerServiceClient, helmRepos []*appv1.Repository, helmCreds []*appv1.RepoCreds, helmOptions *appv1.HelmOptions, enableGenerateManifests map[string]bool) error {
appInstanceLabelKey, err := s.settingsMgr.GetAppInstanceLabelKey()
@@ -465,21 +468,14 @@ func (s *Server) GetManifests(ctx context.Context, q *application.ApplicationMan
return fmt.Errorf("error getting API resources: %w", err)
}
proj, err := argo.GetAppProject(a, applisters.NewAppProjectLister(s.projInformer.GetIndexer()), s.ns, s.settingsMgr, s.db, ctx)
if err != nil {
return fmt.Errorf("error getting app project: %w", err)
}
sources := make([]appv1.ApplicationSource, 0)
if a.Spec.HasMultipleSources() {
for i := range a.Spec.GetSources() {
source := a.Spec.GetSources()[i]
if q.GetRevisionSourceMappings() != nil && len(q.GetRevisionSourceMappings()) > 0 {
if val, ok := q.GetRevisionSourceMappings()[int64(i+1)]; ok {
source.TargetRevision = val
a.Spec.GetSources()[i] = source
}
numOfSources := int64(len(a.Spec.GetSources()))
for i, pos := range q.SourcePositions {
if pos <= 0 || pos > numOfSources {
return fmt.Errorf("source position is out of range")
}
a.Spec.Sources[pos-1].TargetRevision = q.Revisions[i]
}
sources = a.Spec.GetSources()
} else {
@@ -582,13 +578,13 @@ func (s *Server) GetManifestsWithFiles(stream application.ApplicationService_Get
return fmt.Errorf("invalid request: application name is missing")
}
a, err := s.getApplicationEnforceRBACInformer(ctx, rbacpolicy.ActionGet, query.GetProject(), query.GetAppNamespace(), query.GetName())
a, proj, err := s.getApplicationEnforceRBACInformer(ctx, rbacpolicy.ActionGet, query.GetProject(), query.GetAppNamespace(), query.GetName())
if err != nil {
return err
}
var manifestInfo *apiclient.ManifestResponse
err = s.queryRepoServer(ctx, a, func(
err = s.queryRepoServer(ctx, proj, func(
client apiclient.RepoServerServiceClient, helmRepos []*appv1.Repository, helmCreds []*appv1.RepoCreds, helmOptions *appv1.HelmOptions, enableGenerateManifests map[string]bool) error {
appInstanceLabelKey, err := s.settingsMgr.GetAppInstanceLabelKey()
@@ -713,7 +709,7 @@ func (s *Server) Get(ctx context.Context, q *application.ApplicationQuery) (*app
// We must use a client Get instead of an informer Get, because it's common to call Get immediately
// following a Watch (which is not yet powered by an informer), and the Get must reflect what was
// previously seen by the client.
a, err := s.getApplicationEnforceRBACClient(ctx, rbacpolicy.ActionGet, project, appNs, appName, q.GetResourceVersion())
a, proj, err := s.getApplicationEnforceRBACClient(ctx, rbacpolicy.ActionGet, project, appNs, appName, q.GetResourceVersion())
if err != nil {
return nil, err
}
@@ -744,7 +740,7 @@ func (s *Server) Get(ctx context.Context, q *application.ApplicationQuery) (*app
if refreshType == appv1.RefreshTypeHard {
// force refresh cached application details
if err := s.queryRepoServer(ctx, a, func(
if err := s.queryRepoServer(ctx, proj, func(
client apiclient.RepoServerServiceClient,
helmRepos []*appv1.Repository,
_ []*appv1.RepoCreds,
@@ -806,7 +802,7 @@ func (s *Server) Get(ctx context.Context, q *application.ApplicationQuery) (*app
// ListResourceEvents returns a list of event resources
func (s *Server) ListResourceEvents(ctx context.Context, q *application.ApplicationResourceEventsQuery) (*v1.EventList, error) {
a, err := s.getApplicationEnforceRBACInformer(ctx, rbacpolicy.ActionGet, q.GetProject(), q.GetAppNamespace(), q.GetName())
a, _, err := s.getApplicationEnforceRBACInformer(ctx, rbacpolicy.ActionGet, q.GetProject(), q.GetAppNamespace(), q.GetName())
if err != nil {
return nil, err
}
@@ -874,12 +870,12 @@ func (s *Server) validateAndUpdateApp(ctx context.Context, newApp *appv1.Applica
s.projectLock.RLock(newApp.Spec.GetProject())
defer s.projectLock.RUnlock(newApp.Spec.GetProject())
app, err := s.getApplicationEnforceRBACClient(ctx, action, currentProject, newApp.Namespace, newApp.Name, "")
app, proj, err := s.getApplicationEnforceRBACClient(ctx, action, currentProject, newApp.Namespace, newApp.Name, "")
if err != nil {
return nil, err
}
err = s.validateAndNormalizeApp(ctx, newApp, validate)
err = s.validateAndNormalizeApp(ctx, newApp, proj, validate)
if err != nil {
return nil, fmt.Errorf("error validating and normalizing app: %w", err)
}
@@ -978,7 +974,7 @@ func (s *Server) UpdateSpec(ctx context.Context, q *application.ApplicationUpdat
if q.GetSpec() == nil {
return nil, fmt.Errorf("error updating application spec: spec is nil in request")
}
a, err := s.getApplicationEnforceRBACClient(ctx, rbacpolicy.ActionUpdate, q.GetProject(), q.GetAppNamespace(), q.GetName(), "")
a, _, err := s.getApplicationEnforceRBACClient(ctx, rbacpolicy.ActionUpdate, q.GetProject(), q.GetAppNamespace(), q.GetName(), "")
if err != nil {
return nil, err
}
@@ -997,7 +993,7 @@ func (s *Server) UpdateSpec(ctx context.Context, q *application.ApplicationUpdat
// Patch patches an application
func (s *Server) Patch(ctx context.Context, q *application.ApplicationPatchRequest) (*appv1.Application, error) {
app, err := s.getApplicationEnforceRBACClient(ctx, rbacpolicy.ActionGet, q.GetProject(), q.GetAppNamespace(), q.GetName(), "")
app, _, err := s.getApplicationEnforceRBACClient(ctx, rbacpolicy.ActionGet, q.GetProject(), q.GetAppNamespace(), q.GetName(), "")
if err != nil {
return nil, err
}
@@ -1040,11 +1036,35 @@ func (s *Server) Patch(ctx context.Context, q *application.ApplicationPatchReque
return s.validateAndUpdateApp(ctx, newApp, false, true, rbacpolicy.ActionUpdate, q.GetProject())
}
func (s *Server) getAppProject(ctx context.Context, a *appv1.Application, logCtx *log.Entry) (*appv1.AppProject, error) {
proj, err := argo.GetAppProject(a, applisters.NewAppProjectLister(s.projInformer.GetIndexer()), s.ns, s.settingsMgr, s.db, ctx)
if err == nil {
return proj, nil
}
// If there's a permission issue or the app doesn't exist, return a vague error to avoid letting the user enumerate project names.
vagueError := status.Errorf(codes.InvalidArgument, "app is not allowed in project %q, or the project does not exist", a.Spec.Project)
if apierr.IsNotFound(err) {
return nil, vagueError
}
if _, ok := err.(*appv1.ErrApplicationNotAllowedToUseProject); ok {
logCtx.WithFields(map[string]interface{}{
"project": a.Spec.Project,
argocommon.SecurityField: argocommon.SecurityMedium,
}).Warnf("error getting app project: %s", err)
return nil, vagueError
}
return nil, vagueError
}
// Delete removes an application and all associated resources
func (s *Server) Delete(ctx context.Context, q *application.ApplicationDeleteRequest) (*application.ApplicationResponse, error) {
appName := q.GetName()
appNs := s.appNamespaceOrDefault(q.GetAppNamespace())
a, err := s.getApplicationEnforceRBACClient(ctx, rbacpolicy.ActionGet, q.GetProject(), appNs, appName, "")
a, _, err := s.getApplicationEnforceRBACClient(ctx, rbacpolicy.ActionGet, q.GetProject(), appNs, appName, "")
if err != nil {
return nil, err
}
@@ -1199,16 +1219,7 @@ func (s *Server) Watch(q *application.ApplicationQuery, ws application.Applicati
}
}
func (s *Server) validateAndNormalizeApp(ctx context.Context, app *appv1.Application, validate bool) error {
proj, err := argo.GetAppProject(app, applisters.NewAppProjectLister(s.projInformer.GetIndexer()), s.ns, s.settingsMgr, s.db, ctx)
if err != nil {
if apierr.IsNotFound(err) {
// Offer no hint that the project does not exist.
log.Warnf("User attempted to create/update application in non-existent project %q", app.Spec.Project)
return permissionDeniedErr
}
return fmt.Errorf("error getting application's project: %w", err)
}
func (s *Server) validateAndNormalizeApp(ctx context.Context, app *appv1.Application, proj *appv1.AppProject, validate bool) error {
if app.GetName() == "" {
return fmt.Errorf("resource name may not be empty")
}
@@ -1312,7 +1323,7 @@ func (s *Server) getAppResources(ctx context.Context, a *appv1.Application) (*ap
}
func (s *Server) getAppLiveResource(ctx context.Context, action string, q *application.ApplicationResourceRequest) (*appv1.ResourceNode, *rest.Config, *appv1.Application, error) {
a, err := s.getApplicationEnforceRBACInformer(ctx, action, q.GetProject(), q.GetAppNamespace(), q.GetName())
a, _, err := s.getApplicationEnforceRBACInformer(ctx, action, q.GetProject(), q.GetAppNamespace(), q.GetName())
if err != nil {
return nil, nil, nil, err
}
@@ -1449,7 +1460,7 @@ func (s *Server) DeleteResource(ctx context.Context, q *application.ApplicationR
}
func (s *Server) ResourceTree(ctx context.Context, q *application.ResourcesQuery) (*appv1.ApplicationTree, error) {
a, err := s.getApplicationEnforceRBACInformer(ctx, rbacpolicy.ActionGet, q.GetProject(), q.GetAppNamespace(), q.GetApplicationName())
a, _, err := s.getApplicationEnforceRBACInformer(ctx, rbacpolicy.ActionGet, q.GetProject(), q.GetAppNamespace(), q.GetApplicationName())
if err != nil {
return nil, err
}
@@ -1458,7 +1469,7 @@ func (s *Server) ResourceTree(ctx context.Context, q *application.ResourcesQuery
}
func (s *Server) WatchResourceTree(q *application.ResourcesQuery, ws application.ApplicationService_WatchResourceTreeServer) error {
_, err := s.getApplicationEnforceRBACInformer(ws.Context(), rbacpolicy.ActionGet, q.GetProject(), q.GetAppNamespace(), q.GetApplicationName())
_, _, err := s.getApplicationEnforceRBACInformer(ws.Context(), rbacpolicy.ActionGet, q.GetProject(), q.GetAppNamespace(), q.GetApplicationName())
if err != nil {
return err
}
@@ -1475,7 +1486,7 @@ func (s *Server) WatchResourceTree(q *application.ResourcesQuery, ws application
}
func (s *Server) RevisionMetadata(ctx context.Context, q *application.RevisionMetadataQuery) (*appv1.RevisionMetadata, error) {
a, err := s.getApplicationEnforceRBACInformer(ctx, rbacpolicy.ActionGet, q.GetProject(), q.GetAppNamespace(), q.GetName())
a, proj, err := s.getApplicationEnforceRBACInformer(ctx, rbacpolicy.ActionGet, q.GetProject(), q.GetAppNamespace(), q.GetName())
if err != nil {
return nil, err
}
@@ -1485,12 +1496,6 @@ func (s *Server) RevisionMetadata(ctx context.Context, q *application.RevisionMe
if err != nil {
return nil, fmt.Errorf("error getting repository by URL: %w", err)
}
// We need to get some information with the project associated to the app,
// so we'll know whether GPG signatures are enforced.
proj, err := argo.GetAppProject(a, applisters.NewAppProjectLister(s.projInformer.GetIndexer()), s.ns, s.settingsMgr, s.db, ctx)
if err != nil {
return nil, fmt.Errorf("error getting app project: %w", err)
}
conn, repoClient, err := s.repoClientset.NewRepoServerClient()
if err != nil {
return nil, fmt.Errorf("error creating repo server client: %w", err)
@@ -1505,7 +1510,7 @@ func (s *Server) RevisionMetadata(ctx context.Context, q *application.RevisionMe
// RevisionChartDetails returns the helm chart metadata, as fetched from the reposerver
func (s *Server) RevisionChartDetails(ctx context.Context, q *application.RevisionMetadataQuery) (*appv1.ChartDetails, error) {
a, err := s.getApplicationEnforceRBACInformer(ctx, rbacpolicy.ActionGet, q.GetProject(), q.GetAppNamespace(), q.GetName())
a, _, err := s.getApplicationEnforceRBACInformer(ctx, rbacpolicy.ActionGet, q.GetProject(), q.GetAppNamespace(), q.GetName())
if err != nil {
return nil, err
}
@@ -1536,7 +1541,7 @@ func isMatchingResource(q *application.ResourcesQuery, key kube.ResourceKey) boo
}
func (s *Server) ManagedResources(ctx context.Context, q *application.ResourcesQuery) (*application.ManagedResourcesResponse, error) {
a, err := s.getApplicationEnforceRBACInformer(ctx, rbacpolicy.ActionGet, q.GetProject(), q.GetAppNamespace(), q.GetApplicationName())
a, _, err := s.getApplicationEnforceRBACInformer(ctx, rbacpolicy.ActionGet, q.GetProject(), q.GetAppNamespace(), q.GetApplicationName())
if err != nil {
return nil, err
}
@@ -1593,7 +1598,7 @@ func (s *Server) PodLogs(q *application.ApplicationPodLogsQuery, ws application.
}
}
a, err := s.getApplicationEnforceRBACInformer(ws.Context(), rbacpolicy.ActionGet, q.GetProject(), q.GetAppNamespace(), q.GetName())
a, _, err := s.getApplicationEnforceRBACInformer(ws.Context(), rbacpolicy.ActionGet, q.GetProject(), q.GetAppNamespace(), q.GetName())
if err != nil {
return err
}
@@ -1790,19 +1795,11 @@ func isTheSelectedOne(currentNode *appv1.ResourceNode, q *application.Applicatio
// Sync syncs an application to its target state
func (s *Server) Sync(ctx context.Context, syncReq *application.ApplicationSyncRequest) (*appv1.Application, error) {
a, err := s.getApplicationEnforceRBACClient(ctx, rbacpolicy.ActionGet, syncReq.GetProject(), syncReq.GetAppNamespace(), syncReq.GetName(), "")
a, proj, err := s.getApplicationEnforceRBACClient(ctx, rbacpolicy.ActionGet, syncReq.GetProject(), syncReq.GetAppNamespace(), syncReq.GetName(), "")
if err != nil {
return nil, err
}
proj, err := argo.GetAppProject(a, applisters.NewAppProjectLister(s.projInformer.GetIndexer()), s.ns, s.settingsMgr, s.db, ctx)
if err != nil {
if apierr.IsNotFound(err) {
return a, status.Errorf(codes.InvalidArgument, "application references project %s which does not exist", a.Spec.Project)
}
return a, fmt.Errorf("error getting app project: %w", err)
}
s.inferResourcesStatusHealth(a)
if !proj.Spec.SyncWindows.Matches(a).CanSync(true) {
@@ -1813,8 +1810,6 @@ func (s *Server) Sync(ctx context.Context, syncReq *application.ApplicationSyncR
return nil, err
}
source := a.Spec.GetSource()
if syncReq.Manifests != nil {
if err := s.enf.EnforceErr(ctx.Value("claims"), rbacpolicy.ResourceApplications, rbacpolicy.ActionOverride, a.RBACName(s.ns)); err != nil {
return nil, err
@@ -1826,14 +1821,10 @@ func (s *Server) Sync(ctx context.Context, syncReq *application.ApplicationSyncR
if a.DeletionTimestamp != nil {
return nil, status.Errorf(codes.FailedPrecondition, "application is deleting")
}
if a.Spec.SyncPolicy != nil && a.Spec.SyncPolicy.Automated != nil && !syncReq.GetDryRun() {
if syncReq.GetRevision() != "" && syncReq.GetRevision() != text.FirstNonEmpty(source.TargetRevision, "HEAD") {
return nil, status.Errorf(codes.FailedPrecondition, "Cannot sync to %s: auto-sync currently set to %s", syncReq.GetRevision(), source.TargetRevision)
}
}
revision, displayRevision, err := s.resolveRevision(ctx, a, syncReq)
revision, displayRevision, sourceRevisions, displayRevisions, err := s.resolveSourceRevisions(ctx, a, syncReq)
if err != nil {
return nil, status.Errorf(codes.FailedPrecondition, err.Error())
return nil, err
}
var retry *appv1.RetryStrategy
@@ -1871,6 +1862,8 @@ func (s *Server) Sync(ctx context.Context, syncReq *application.ApplicationSyncR
SyncStrategy: syncReq.Strategy,
Resources: resources,
Manifests: syncReq.Manifests,
Sources: a.Spec.Sources,
Revisions: sourceRevisions,
},
InitiatedBy: appv1.OperationInitiator{Username: session.Username(ctx)},
Info: syncReq.Infos,
@@ -1890,7 +1883,12 @@ func (s *Server) Sync(ctx context.Context, syncReq *application.ApplicationSyncR
if len(syncReq.Resources) > 0 {
partial = "partial "
}
reason := fmt.Sprintf("initiated %ssync to %s", partial, displayRevision)
var reason string
if a.Spec.HasMultipleSources() {
reason = fmt.Sprintf("initiated %ssync to %s", partial, strings.Join(displayRevisions, ","))
} else {
reason = fmt.Sprintf("initiated %ssync to %s", partial, displayRevision)
}
if syncReq.Manifests != nil {
reason = fmt.Sprintf("initiated %ssync locally", partial)
}
@@ -1898,8 +1896,50 @@ func (s *Server) Sync(ctx context.Context, syncReq *application.ApplicationSyncR
return a, nil
}
func (s *Server) resolveSourceRevisions(ctx context.Context, a *appv1.Application, syncReq *application.ApplicationSyncRequest) (string, string, []string, []string, error) {
if a.Spec.HasMultipleSources() {
numOfSources := int64(len(a.Spec.GetSources()))
sourceRevisions := make([]string, numOfSources)
displayRevisions := make([]string, numOfSources)
sources := a.Spec.GetSources()
for i, pos := range syncReq.SourcePositions {
if pos <= 0 || pos > numOfSources {
return "", "", nil, nil, fmt.Errorf("source position is out of range")
}
sources[pos-1].TargetRevision = syncReq.Revisions[i]
}
for index, source := range sources {
if a.Spec.SyncPolicy != nil && a.Spec.SyncPolicy.Automated != nil && !syncReq.GetDryRun() {
if text.FirstNonEmpty(a.Spec.GetSources()[index].TargetRevision, "HEAD") != text.FirstNonEmpty(source.TargetRevision, "HEAD") {
return "", "", nil, nil, status.Errorf(codes.FailedPrecondition, "Cannot sync source %s to %s: auto-sync currently set to %s", source.RepoURL, source.TargetRevision, a.Spec.Sources[index].TargetRevision)
}
}
revision, displayRevision, err := s.resolveRevision(ctx, a, syncReq, index)
if err != nil {
return "", "", nil, nil, status.Errorf(codes.FailedPrecondition, err.Error())
}
sourceRevisions[index] = revision
displayRevisions[index] = displayRevision
}
return "", "", sourceRevisions, displayRevisions, nil
} else {
source := a.Spec.GetSource()
if a.Spec.SyncPolicy != nil && a.Spec.SyncPolicy.Automated != nil && !syncReq.GetDryRun() {
if syncReq.GetRevision() != "" && syncReq.GetRevision() != text.FirstNonEmpty(source.TargetRevision, "HEAD") {
return "", "", nil, nil, status.Errorf(codes.FailedPrecondition, "Cannot sync to %s: auto-sync currently set to %s", syncReq.GetRevision(), source.TargetRevision)
}
}
revision, displayRevision, err := s.resolveRevision(ctx, a, syncReq, -1)
if err != nil {
return "", "", nil, nil, status.Errorf(codes.FailedPrecondition, err.Error())
}
return revision, displayRevision, nil, nil, nil
}
}
func (s *Server) Rollback(ctx context.Context, rollbackReq *application.ApplicationRollbackRequest) (*appv1.Application, error) {
a, err := s.getApplicationEnforceRBACClient(ctx, rbacpolicy.ActionSync, rollbackReq.GetProject(), rollbackReq.GetAppNamespace(), rollbackReq.GetName(), "")
a, _, err := s.getApplicationEnforceRBACClient(ctx, rbacpolicy.ActionSync, rollbackReq.GetProject(), rollbackReq.GetAppNamespace(), rollbackReq.GetName(), "")
if err != nil {
return nil, err
}
@@ -1958,7 +1998,7 @@ func (s *Server) Rollback(ctx context.Context, rollbackReq *application.Applicat
}
func (s *Server) ListLinks(ctx context.Context, req *application.ListAppLinksRequest) (*application.LinksResponse, error) {
a, err := s.getApplicationEnforceRBACClient(ctx, rbacpolicy.ActionGet, req.GetProject(), req.GetNamespace(), req.GetName(), "")
a, proj, err := s.getApplicationEnforceRBACClient(ctx, rbacpolicy.ActionGet, req.GetProject(), req.GetNamespace(), req.GetName(), "")
if err != nil {
return nil, err
}
@@ -1973,7 +2013,7 @@ func (s *Server) ListLinks(ctx context.Context, req *application.ListAppLinksReq
return nil, fmt.Errorf("failed to read application deep links from configmap: %w", err)
}
clstObj, _, err := s.getObjectsForDeepLinks(ctx, a)
clstObj, _, err := s.getObjectsForDeepLinks(ctx, a, proj)
if err != nil {
return nil, err
}
@@ -1988,12 +2028,7 @@ func (s *Server) ListLinks(ctx context.Context, req *application.ListAppLinksReq
return finalList, nil
}
func (s *Server) getObjectsForDeepLinks(ctx context.Context, app *appv1.Application) (cluster *unstructured.Unstructured, project *unstructured.Unstructured, err error) {
proj, err := argo.GetAppProject(app, applisters.NewAppProjectLister(s.projInformer.GetIndexer()), s.ns, s.settingsMgr, s.db, ctx)
if err != nil {
return nil, nil, fmt.Errorf("error getting app project: %w", err)
}
func (s *Server) getObjectsForDeepLinks(ctx context.Context, app *appv1.Application, proj *appv1.AppProject) (cluster *unstructured.Unstructured, project *unstructured.Unstructured, err error) {
// sanitize project jwt tokens
proj.Status = appv1.AppProjectStatus{}
@@ -2056,7 +2091,12 @@ func (s *Server) ListResourceLinks(ctx context.Context, req *application.Applica
return nil, err
}
clstObj, projObj, err := s.getObjectsForDeepLinks(ctx, app)
proj, err := s.getAppProject(ctx, app, log.WithField("application", app.GetName()))
if err != nil {
return nil, err
}
clstObj, projObj, err := s.getObjectsForDeepLinks(ctx, app, proj)
if err != nil {
return nil, err
}
@@ -2070,16 +2110,35 @@ func (s *Server) ListResourceLinks(ctx context.Context, req *application.Applica
return finalList, nil
}
func getAmbiguousRevision(app *appv1.Application, syncReq *application.ApplicationSyncRequest, sourceIndex int) string {
ambiguousRevision := ""
if app.Spec.HasMultipleSources() {
for i, pos := range syncReq.SourcePositions {
if pos == int64(sourceIndex) {
ambiguousRevision = syncReq.Revisions[i]
}
}
if ambiguousRevision == "" {
ambiguousRevision = app.Spec.Sources[sourceIndex].TargetRevision
}
} else {
ambiguousRevision = syncReq.GetRevision()
if ambiguousRevision == "" {
ambiguousRevision = app.Spec.GetSource().TargetRevision
}
}
return ambiguousRevision
}
// resolveRevision resolves the revision specified either in the sync request, or the
// application source, into a concrete revision that will be used for a sync operation.
func (s *Server) resolveRevision(ctx context.Context, app *appv1.Application, syncReq *application.ApplicationSyncRequest) (string, string, error) {
func (s *Server) resolveRevision(ctx context.Context, app *appv1.Application, syncReq *application.ApplicationSyncRequest, sourceIndex int) (string, string, error) {
if syncReq.Manifests != nil {
return "", "", nil
}
ambiguousRevision := syncReq.GetRevision()
if ambiguousRevision == "" {
ambiguousRevision = app.Spec.GetSource().TargetRevision
}
ambiguousRevision := getAmbiguousRevision(app, syncReq, sourceIndex)
repo, err := s.db.GetRepository(ctx, app.Spec.GetSource().RepoURL)
if err != nil {
return "", "", fmt.Errorf("error getting repository by URL: %w", err)
@@ -2090,7 +2149,7 @@ func (s *Server) resolveRevision(ctx context.Context, app *appv1.Application, sy
}
defer ioutil.Close(conn)
source := app.Spec.GetSource()
source := app.Spec.GetSourcePtrByIndex(sourceIndex)
if !source.IsHelm() {
if git.IsCommitSHA(ambiguousRevision) {
// If it's already a commit SHA, then no need to look it up
@@ -2102,6 +2161,7 @@ func (s *Server) resolveRevision(ctx context.Context, app *appv1.Application, sy
Repo: repo,
App: app,
AmbiguousRevision: ambiguousRevision,
SourceIndex: int64(sourceIndex),
})
if err != nil {
return "", "", fmt.Errorf("error resolving repo revision: %w", err)
@@ -2112,7 +2172,7 @@ func (s *Server) resolveRevision(ctx context.Context, app *appv1.Application, sy
func (s *Server) TerminateOperation(ctx context.Context, termOpReq *application.OperationTerminateRequest) (*application.OperationTerminateResponse, error) {
appName := termOpReq.GetName()
appNs := s.appNamespaceOrDefault(termOpReq.GetAppNamespace())
a, err := s.getApplicationEnforceRBACClient(ctx, rbacpolicy.ActionSync, termOpReq.GetProject(), appNs, appName, "")
a, _, err := s.getApplicationEnforceRBACClient(ctx, rbacpolicy.ActionSync, termOpReq.GetProject(), appNs, appName, "")
if err != nil {
return nil, err
}
@@ -2185,7 +2245,7 @@ func (s *Server) ListResourceActions(ctx context.Context, q *application.Applica
func (s *Server) getUnstructuredLiveResourceOrApp(ctx context.Context, rbacRequest string, q *application.ApplicationResourceRequest) (obj *unstructured.Unstructured, res *appv1.ResourceNode, app *appv1.Application, config *rest.Config, err error) {
if q.GetKind() == applicationType.ApplicationKind && q.GetGroup() == applicationType.Group && q.GetName() == q.GetResourceName() {
app, err = s.getApplicationEnforceRBACInformer(ctx, rbacRequest, q.GetProject(), q.GetAppNamespace(), q.GetName())
app, _, err = s.getApplicationEnforceRBACInformer(ctx, rbacRequest, q.GetProject(), q.GetAppNamespace(), q.GetName())
if err != nil {
return nil, nil, nil, nil, err
}
@@ -2281,6 +2341,11 @@ func (s *Server) RunResourceAction(ctx context.Context, q *application.ResourceA
}
}
proj, err := s.getAppProject(ctx, a, log.WithField("application", a.Name))
if err != nil {
return nil, err
}
// First, make sure all the returned resources are permitted, for each operation.
// Also perform create with dry-runs for all create-operation resources.
// This is performed separately to reduce the risk of only some of the resources being successfully created later.
@@ -2288,7 +2353,7 @@ func (s *Server) RunResourceAction(ctx context.Context, q *application.ResourceA
// the dry-run for relevant apply/delete operation would have to be invoked as well.
for _, impactedResource := range newObjects {
newObj := impactedResource.UnstructuredObj
err := s.verifyResourcePermitted(ctx, app, newObj)
err := s.verifyResourcePermitted(ctx, app, proj, newObj)
if err != nil {
return nil, err
}
@@ -2382,14 +2447,7 @@ func (s *Server) patchResource(ctx context.Context, config *rest.Config, liveObj
return &application.ApplicationResponse{}, nil
}
func (s *Server) verifyResourcePermitted(ctx context.Context, app *appv1.Application, obj *unstructured.Unstructured) error {
proj, err := argo.GetAppProject(app, applisters.NewAppProjectLister(s.projInformer.GetIndexer()), s.ns, s.settingsMgr, s.db, ctx)
if err != nil {
if apierr.IsNotFound(err) {
return fmt.Errorf("application references project %s which does not exist", app.Spec.Project)
}
return fmt.Errorf("failed to get project %s: %w", app.Spec.Project, err)
}
func (s *Server) verifyResourcePermitted(ctx context.Context, app *appv1.Application, proj *appv1.AppProject, obj *unstructured.Unstructured) error {
permitted, err := proj.IsResourcePermitted(schema.GroupKind{Group: obj.GroupVersionKind().Group, Kind: obj.GroupVersionKind().Kind}, obj.GetNamespace(), app.Spec.Destination, func(project string) ([]*appv1.Cluster, error) {
clusters, err := s.db.GetProjectClusters(context.TODO(), project)
if err != nil {
@@ -2449,16 +2507,11 @@ func splitStatusPatch(patch []byte) ([]byte, []byte, error) {
}
func (s *Server) GetApplicationSyncWindows(ctx context.Context, q *application.ApplicationSyncWindowsQuery) (*application.ApplicationSyncWindowsResponse, error) {
a, err := s.getApplicationEnforceRBACClient(ctx, rbacpolicy.ActionGet, q.GetProject(), q.GetAppNamespace(), q.GetName(), "")
a, proj, err := s.getApplicationEnforceRBACClient(ctx, rbacpolicy.ActionGet, q.GetProject(), q.GetAppNamespace(), q.GetName(), "")
if err != nil {
return nil, err
}
proj, err := argo.GetAppProject(a, applisters.NewAppProjectLister(s.projInformer.GetIndexer()), s.ns, s.settingsMgr, s.db, ctx)
if err != nil {
return nil, fmt.Errorf("error getting app project: %w", err)
}
windows := proj.Spec.SyncWindows.Matches(a)
sync := windows.CanSync(true)

View File

@@ -69,7 +69,8 @@ message ApplicationManifestQuery {
optional string revision = 2;
optional string appNamespace = 3;
optional string project = 4;
map<int64, string> revisionSourceMappings = 5;
repeated int64 sourcePositions = 5;
repeated string revisions = 6;
}
message FileChunk {
@@ -130,6 +131,8 @@ message ApplicationSyncRequest {
optional SyncOptions syncOptions = 11;
optional string appNamespace = 12;
optional string project = 13;
repeated int64 sourcePositions = 14;
repeated string revisions = 15;
}
// ApplicationUpdateSpecRequest is a request to update application spec

View File

@@ -43,6 +43,7 @@ import (
"github.com/argoproj/argo-cd/v2/common"
"github.com/argoproj/argo-cd/v2/pkg/apiclient/application"
appsv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1"
appv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1"
apps "github.com/argoproj/argo-cd/v2/pkg/client/clientset/versioned/fake"
appinformer "github.com/argoproj/argo-cd/v2/pkg/client/informers/externalversions"
"github.com/argoproj/argo-cd/v2/reposerver/apiclient"
@@ -1819,7 +1820,7 @@ func TestServer_GetApplicationSyncWindowsState(t *testing.T) {
appServer := newTestAppServer(t, testApp)
active, err := appServer.GetApplicationSyncWindows(context.Background(), &application.ApplicationSyncWindowsQuery{Name: &testApp.Name})
assert.Contains(t, err.Error(), "not found")
assert.Contains(t, err.Error(), "not exist")
assert.Nil(t, active)
})
}
@@ -2531,7 +2532,16 @@ func TestAppNamespaceRestrictions(t *testing.T) {
t.Run("Get application in other namespace when allowed", func(t *testing.T) {
testApp := newTestApp()
testApp.Namespace = "argocd-1"
appServer := newTestAppServer(t, testApp)
testApp.Spec.Project = "other-ns"
otherNsProj := &appsv1.AppProject{
ObjectMeta: metav1.ObjectMeta{Name: "other-ns", Namespace: "default"},
Spec: appsv1.AppProjectSpec{
SourceRepos: []string{"*"},
Destinations: []appsv1.ApplicationDestination{{Server: "*", Namespace: "*"}},
SourceNamespaces: []string{"argocd-1"},
},
}
appServer := newTestAppServer(t, testApp, otherNsProj)
appServer.enabledNamespaces = []string{"argocd-1"}
app, err := appServer.Get(context.TODO(), &application.ApplicationQuery{
Name: pointer.String("test-app"),
@@ -2542,6 +2552,28 @@ func TestAppNamespaceRestrictions(t *testing.T) {
require.Equal(t, "argocd-1", app.Namespace)
require.Equal(t, "test-app", app.Name)
})
t.Run("Get application in other namespace when project is not allowed", func(t *testing.T) {
testApp := newTestApp()
testApp.Namespace = "argocd-1"
testApp.Spec.Project = "other-ns"
otherNsProj := &appsv1.AppProject{
ObjectMeta: metav1.ObjectMeta{Name: "other-ns", Namespace: "default"},
Spec: appsv1.AppProjectSpec{
SourceRepos: []string{"*"},
Destinations: []appsv1.ApplicationDestination{{Server: "*", Namespace: "*"}},
SourceNamespaces: []string{"argocd-2"},
},
}
appServer := newTestAppServer(t, testApp, otherNsProj)
appServer.enabledNamespaces = []string{"argocd-1"}
app, err := appServer.Get(context.TODO(), &application.ApplicationQuery{
Name: pointer.String("test-app"),
AppNamespace: pointer.String("argocd-1"),
})
require.Error(t, err)
require.Nil(t, app)
require.ErrorContains(t, err, "app is not allowed in project")
})
t.Run("Create application in other namespace when allowed", func(t *testing.T) {
testApp := newTestApp()
testApp.Namespace = "argocd-1"
@@ -2584,7 +2616,7 @@ func TestAppNamespaceRestrictions(t *testing.T) {
})
require.Error(t, err)
require.Nil(t, app)
require.ErrorContains(t, err, "not allowed to use project")
require.ErrorContains(t, err, "app is not allowed in project")
})
t.Run("Create application in other namespace when not allowed by configuration", func(t *testing.T) {
@@ -2608,5 +2640,207 @@ func TestAppNamespaceRestrictions(t *testing.T) {
require.Nil(t, app)
require.ErrorContains(t, err, "namespace 'argocd-1' is not permitted")
})
t.Run("Get application sync window in other namespace when project is allowed", func(t *testing.T) {
testApp := newTestApp()
testApp.Namespace = "argocd-1"
testApp.Spec.Project = "other-ns"
otherNsProj := &appsv1.AppProject{
ObjectMeta: metav1.ObjectMeta{Name: "other-ns", Namespace: "default"},
Spec: appsv1.AppProjectSpec{
SourceRepos: []string{"*"},
Destinations: []appsv1.ApplicationDestination{{Server: "*", Namespace: "*"}},
SourceNamespaces: []string{"argocd-1"},
},
}
appServer := newTestAppServer(t, testApp, otherNsProj)
appServer.enabledNamespaces = []string{"argocd-1"}
active, err := appServer.GetApplicationSyncWindows(context.TODO(), &application.ApplicationSyncWindowsQuery{Name: &testApp.Name, AppNamespace: &testApp.Namespace})
assert.NoError(t, err)
assert.Equal(t, 0, len(active.ActiveWindows))
})
t.Run("Get application sync window in other namespace when project is not allowed", func(t *testing.T) {
testApp := newTestApp()
testApp.Namespace = "argocd-1"
testApp.Spec.Project = "other-ns"
otherNsProj := &appsv1.AppProject{
ObjectMeta: metav1.ObjectMeta{Name: "other-ns", Namespace: "default"},
Spec: appsv1.AppProjectSpec{
SourceRepos: []string{"*"},
Destinations: []appsv1.ApplicationDestination{{Server: "*", Namespace: "*"}},
SourceNamespaces: []string{"argocd-2"},
},
}
appServer := newTestAppServer(t, testApp, otherNsProj)
appServer.enabledNamespaces = []string{"argocd-1"}
active, err := appServer.GetApplicationSyncWindows(context.TODO(), &application.ApplicationSyncWindowsQuery{Name: &testApp.Name, AppNamespace: &testApp.Namespace})
require.Error(t, err)
require.Nil(t, active)
require.ErrorContains(t, err, "app is not allowed in project")
})
t.Run("Get list of links in other namespace when project is not allowed", func(t *testing.T) {
testApp := newTestApp()
testApp.Namespace = "argocd-1"
testApp.Spec.Project = "other-ns"
otherNsProj := &appsv1.AppProject{
ObjectMeta: metav1.ObjectMeta{Name: "other-ns", Namespace: "default"},
Spec: appsv1.AppProjectSpec{
SourceRepos: []string{"*"},
Destinations: []appsv1.ApplicationDestination{{Server: "*", Namespace: "*"}},
SourceNamespaces: []string{"argocd-2"},
},
}
appServer := newTestAppServer(t, testApp, otherNsProj)
appServer.enabledNamespaces = []string{"argocd-1"}
links, err := appServer.ListLinks(context.TODO(), &application.ListAppLinksRequest{
Name: pointer.String("test-app"),
Namespace: pointer.String("argocd-1"),
})
require.Error(t, err)
require.Nil(t, links)
require.ErrorContains(t, err, "app is not allowed in project")
})
t.Run("Get list of links in other namespace when project is allowed", func(t *testing.T) {
testApp := newTestApp()
testApp.Namespace = "argocd-1"
testApp.Spec.Project = "other-ns"
otherNsProj := &appsv1.AppProject{
ObjectMeta: metav1.ObjectMeta{Name: "other-ns", Namespace: "default"},
Spec: appsv1.AppProjectSpec{
SourceRepos: []string{"*"},
Destinations: []appsv1.ApplicationDestination{{Server: "*", Namespace: "*"}},
SourceNamespaces: []string{"argocd-1"},
},
}
appServer := newTestAppServer(t, testApp, otherNsProj)
appServer.enabledNamespaces = []string{"argocd-1"}
links, err := appServer.ListLinks(context.TODO(), &application.ListAppLinksRequest{
Name: pointer.String("test-app"),
Namespace: pointer.String("argocd-1"),
})
require.NoError(t, err)
assert.Equal(t, 0, len(links.Items))
})
}
func TestGetAmbiguousRevision_MultiSource(t *testing.T) {
app := &appv1.Application{
Spec: appv1.ApplicationSpec{
Sources: []appv1.ApplicationSource{
{
TargetRevision: "revision1",
},
{
TargetRevision: "revision2",
},
},
},
}
syncReq := &application.ApplicationSyncRequest{
SourcePositions: []int64{0, 1},
Revisions: []string{"rev1", "rev2"},
}
sourceIndex := 0
expected := "rev1"
result := getAmbiguousRevision(app, syncReq, sourceIndex)
if result != expected {
t.Errorf("Expected ambiguous revision to be %s, but got %s", expected, result)
}
sourceIndex = 1
expected = "rev2"
result = getAmbiguousRevision(app, syncReq, sourceIndex)
if result != expected {
t.Errorf("Expected ambiguous revision to be %s, but got %s", expected, result)
}
// Test when app.Spec.HasMultipleSources() is false
app.Spec = appv1.ApplicationSpec{
Source: &appv1.ApplicationSource{
TargetRevision: "revision3",
},
Sources: nil,
}
syncReq = &application.ApplicationSyncRequest{
Revision: strToPtr("revision3"),
}
expected = "revision3"
result = getAmbiguousRevision(app, syncReq, sourceIndex)
if result != expected {
t.Errorf("Expected ambiguous revision to be %s, but got %s", expected, result)
}
}
func TestGetAmbiguousRevision_SingleSource(t *testing.T) {
app := &appv1.Application{
Spec: appv1.ApplicationSpec{
Source: &appv1.ApplicationSource{
TargetRevision: "revision1",
},
},
}
syncReq := &application.ApplicationSyncRequest{
Revision: strToPtr("rev1"),
}
// Test when app.Spec.HasMultipleSources() is true
sourceIndex := 1
expected := "rev1"
result := getAmbiguousRevision(app, syncReq, sourceIndex)
if result != expected {
t.Errorf("Expected ambiguous revision to be %s, but got %s", expected, result)
}
}
func TestServer_ResolveSourceRevisions_MultiSource(t *testing.T) {
s := newTestAppServer(t)
ctx := context.Background()
a := &appv1.Application{
Spec: appv1.ApplicationSpec{
Sources: []appv1.ApplicationSource{
{
RepoURL: "https://github.com/example/repo.git",
},
},
},
}
syncReq := &application.ApplicationSyncRequest{
SourcePositions: []int64{1},
Revisions: []string{"HEAD"},
}
revision, displayRevision, sourceRevisions, displayRevisions, err := s.resolveSourceRevisions(ctx, a, syncReq)
assert.NoError(t, err)
assert.Equal(t, "", revision)
assert.Equal(t, "", displayRevision)
assert.Equal(t, []string{fakeResolveRevisionResponse().Revision}, sourceRevisions)
assert.Equal(t, []string{fakeResolveRevisionResponse().AmbiguousRevision}, displayRevisions)
}
func TestServer_ResolveSourceRevisions_SingleSource(t *testing.T) {
s := newTestAppServer(t)
ctx := context.Background()
a := &appv1.Application{
Spec: appv1.ApplicationSpec{
Source: &appv1.ApplicationSource{
RepoURL: "https://github.com/example/repo.git",
},
},
}
syncReq := &application.ApplicationSyncRequest{
Revision: strToPtr("HEAD"),
}
revision, displayRevision, sourceRevisions, displayRevisions, err := s.resolveSourceRevisions(ctx, a, syncReq)
assert.NoError(t, err)
assert.Equal(t, fakeResolveRevisionResponse().Revision, revision)
assert.Equal(t, fakeResolveRevisionResponse().AmbiguousRevision, displayRevision)
assert.Equal(t, ([]string)(nil), sourceRevisions)
assert.Equal(t, ([]string)(nil), displayRevisions)
}

View File

@@ -654,7 +654,7 @@ func TestRepositoryServerGetAppDetails(t *testing.T) {
s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projLister, testNamespace, settingsMgr)
resp, err := s.GetAppDetails(context.TODO(), &repository.RepoAppDetailsQuery{
Source: guestbookApp.Spec.GetSourcePtr(0),
Source: guestbookApp.Spec.GetSourcePtrByIndex(0),
AppName: "guestbook",
AppProject: "default",
})
@@ -752,7 +752,7 @@ func TestRepositoryServerGetAppDetails(t *testing.T) {
s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projLister, testNamespace, settingsMgr)
resp, err := s.GetAppDetails(context.TODO(), &repository.RepoAppDetailsQuery{
Source: guestbookApp.Spec.GetSourcePtr(0),
Source: guestbookApp.Spec.GetSourcePtrByIndex(0),
AppName: "guestbook",
AppProject: "mismatch",
})

View File

@@ -432,7 +432,7 @@ func TestNamespacedInvalidAppProject(t *testing.T) {
Then().
// We're not allowed to infer whether the project exists based on this error message. Instead, we get a generic
// permission denied error.
Expect(Error("", "permission denied"))
Expect(Error("", "is not allowed"))
}
func TestNamespacedAppDeletion(t *testing.T) {

View File

@@ -547,7 +547,7 @@ func TestInvalidAppProject(t *testing.T) {
Then().
// We're not allowed to infer whether the project exists based on this error message. Instead, we get a generic
// permission denied error.
Expect(Error("", "permission denied"))
Expect(Error("", "is not allowed"))
}
func TestAppDeletion(t *testing.T) {

View File

@@ -54,12 +54,14 @@ func TestDeclarativeInvalidProject(t *testing.T) {
Expect(Success("")).
Expect(HealthIs(health.HealthStatusUnknown)).
Expect(SyncStatusIs(SyncStatusCodeUnknown)).
Expect(Condition(ApplicationConditionInvalidSpecError, "Application referencing project garbage which does not exist")).
When().
Delete(false).
Then().
Expect(Success("")).
Expect(DoesNotExist())
Expect(Condition(ApplicationConditionInvalidSpecError, "Application referencing project garbage which does not exist"))
// TODO: you can`t delete application with invalid project due to enforcment that was recently added,
// in https://github.com/argoproj/argo-cd/security/advisories/GHSA-2gvw-w6fj-7m3c
//When().
//Delete(false).
//Then().
//Expect(Success("")).
//Expect(DoesNotExist())
}
func TestDeclarativeInvalidRepoURL(t *testing.T) {

View File

@@ -700,8 +700,7 @@ func GetAppProject(app *argoappv1.Application, projLister applicationsv1.AppProj
return nil, err
}
if !proj.IsAppNamespacePermitted(app, ns) {
return nil, fmt.Errorf("application '%s' in namespace '%s' is not allowed to use project '%s'",
app.Name, app.Namespace, proj.Name)
return nil, argoappv1.NewErrApplicationNotAllowedToUseProject(app.Name, app.Namespace, proj.Name)
}
return proj, nil
}

View File

@@ -11,6 +11,7 @@ import (
"github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1"
"github.com/argoproj/argo-cd/v2/util/argo"
"github.com/argoproj/argo-cd/v2/util/argo/managedfields"
"github.com/argoproj/argo-cd/v2/util/argo/normalizers"
appstatecache "github.com/argoproj/argo-cd/v2/util/cache/appstate"
"github.com/argoproj/gitops-engine/pkg/diff"
@@ -34,7 +35,7 @@ func NewDiffConfigBuilder() *DiffConfigBuilder {
}
// WithDiffSettings will set the diff settings in the builder.
func (b *DiffConfigBuilder) WithDiffSettings(id []v1alpha1.ResourceIgnoreDifferences, o map[string]v1alpha1.ResourceOverride, ignoreAggregatedRoles bool) *DiffConfigBuilder {
func (b *DiffConfigBuilder) WithDiffSettings(id []v1alpha1.ResourceIgnoreDifferences, o map[string]v1alpha1.ResourceOverride, ignoreAggregatedRoles bool, ignoreNormalizerOpts normalizers.IgnoreNormalizerOpts) *DiffConfigBuilder {
ignores := id
if ignores == nil {
ignores = []v1alpha1.ResourceIgnoreDifferences{}
@@ -47,6 +48,7 @@ func (b *DiffConfigBuilder) WithDiffSettings(id []v1alpha1.ResourceIgnoreDiffere
}
b.diffConfig.overrides = overrides
b.diffConfig.ignoreAggregatedRoles = ignoreAggregatedRoles
b.diffConfig.ignoreNormalizerOpts = ignoreNormalizerOpts
return b
}
@@ -161,6 +163,8 @@ type DiffConfig interface {
ServerSideDiff() bool
ServerSideDryRunner() diff.ServerSideDryRunner
IgnoreMutationWebhook() bool
IgnoreNormalizerOpts() normalizers.IgnoreNormalizerOpts
}
// diffConfig defines the configurations used while applying diffs.
@@ -180,6 +184,7 @@ type diffConfig struct {
serverSideDiff bool
serverSideDryRunner diff.ServerSideDryRunner
ignoreMutationWebhook bool
ignoreNormalizerOpts normalizers.IgnoreNormalizerOpts
}
func (c *diffConfig) Ignores() []v1alpha1.ResourceIgnoreDifferences {
@@ -227,6 +232,9 @@ func (c *diffConfig) ServerSideDiff() bool {
func (c *diffConfig) IgnoreMutationWebhook() bool {
return c.ignoreMutationWebhook
}
func (c *diffConfig) IgnoreNormalizerOpts() normalizers.IgnoreNormalizerOpts {
return c.ignoreNormalizerOpts
}
// Validate will check the current state of this diffConfig and return
// error if it finds any required configuration missing.
@@ -279,7 +287,7 @@ func StateDiffs(lives, configs []*unstructured.Unstructured, diffConfig DiffConf
return nil, fmt.Errorf("failed to perform pre-diff normalization: %w", err)
}
diffNormalizer, err := newDiffNormalizer(diffConfig.Ignores(), diffConfig.Overrides())
diffNormalizer, err := newDiffNormalizer(diffConfig.Ignores(), diffConfig.Overrides(), diffConfig.IgnoreNormalizerOpts())
if err != nil {
return nil, fmt.Errorf("failed to create diff normalizer: %w", err)
}

View File

@@ -10,6 +10,7 @@ import (
"github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1"
testutil "github.com/argoproj/argo-cd/v2/test"
argo "github.com/argoproj/argo-cd/v2/util/argo/diff"
"github.com/argoproj/argo-cd/v2/util/argo/normalizers"
"github.com/argoproj/argo-cd/v2/util/argo/testdata"
appstatecache "github.com/argoproj/argo-cd/v2/util/cache/appstate"
)
@@ -40,7 +41,7 @@ func TestStateDiff(t *testing.T) {
diffConfig := func(t *testing.T, params *diffConfigParams) argo.DiffConfig {
t.Helper()
diffConfig, err := argo.NewDiffConfigBuilder().
WithDiffSettings(params.ignores, params.overrides, params.ignoreRoles).
WithDiffSettings(params.ignores, params.overrides, params.ignoreRoles, normalizers.IgnoreNormalizerOpts{}).
WithTracking(params.label, params.trackingMethod).
WithNoCache().
Build()
@@ -185,7 +186,7 @@ func TestDiffConfigBuilder(t *testing.T) {
// when
diffConfig, err := argo.NewDiffConfigBuilder().
WithDiffSettings(f.ignores, f.overrides, f.ignoreRoles).
WithDiffSettings(f.ignores, f.overrides, f.ignoreRoles, normalizers.IgnoreNormalizerOpts{}).
WithTracking(f.label, f.trackingMethod).
WithNoCache().
Build()
@@ -209,7 +210,7 @@ func TestDiffConfigBuilder(t *testing.T) {
// when
diffConfig, err := argo.NewDiffConfigBuilder().
WithDiffSettings(nil, nil, f.ignoreRoles).
WithDiffSettings(nil, nil, f.ignoreRoles, normalizers.IgnoreNormalizerOpts{}).
WithTracking(f.label, f.trackingMethod).
WithNoCache().
Build()
@@ -231,7 +232,7 @@ func TestDiffConfigBuilder(t *testing.T) {
// when
diffConfig, err := argo.NewDiffConfigBuilder().
WithDiffSettings(f.ignores, f.overrides, f.ignoreRoles).
WithDiffSettings(f.ignores, f.overrides, f.ignoreRoles, normalizers.IgnoreNormalizerOpts{}).
WithTracking(f.label, f.trackingMethod).
WithCache(&appstatecache.Cache{}, "").
Build()
@@ -246,7 +247,7 @@ func TestDiffConfigBuilder(t *testing.T) {
// when
diffConfig, err := argo.NewDiffConfigBuilder().
WithDiffSettings(f.ignores, f.overrides, f.ignoreRoles).
WithDiffSettings(f.ignores, f.overrides, f.ignoreRoles, normalizers.IgnoreNormalizerOpts{}).
WithTracking(f.label, f.trackingMethod).
WithCache(nil, f.appName).
Build()

View File

@@ -15,7 +15,7 @@ func Normalize(lives, configs []*unstructured.Unstructured, diffConfig DiffConfi
if err != nil {
return nil, err
}
diffNormalizer, err := newDiffNormalizer(diffConfig.Ignores(), diffConfig.Overrides())
diffNormalizer, err := newDiffNormalizer(diffConfig.Ignores(), diffConfig.Overrides(), diffConfig.IgnoreNormalizerOpts())
if err != nil {
return nil, err
}
@@ -40,8 +40,8 @@ func Normalize(lives, configs []*unstructured.Unstructured, diffConfig DiffConfi
}
// newDiffNormalizer creates normalizer that uses Argo CD and application settings to normalize the resource prior to diffing.
func newDiffNormalizer(ignore []v1alpha1.ResourceIgnoreDifferences, overrides map[string]v1alpha1.ResourceOverride) (diff.Normalizer, error) {
ignoreNormalizer, err := normalizers.NewIgnoreNormalizer(ignore, overrides)
func newDiffNormalizer(ignore []v1alpha1.ResourceIgnoreDifferences, overrides map[string]v1alpha1.ResourceOverride, opts normalizers.IgnoreNormalizerOpts) (diff.Normalizer, error) {
ignoreNormalizer, err := normalizers.NewIgnoreNormalizer(ignore, overrides, opts)
if err != nil {
return nil, err
}

View File

@@ -10,6 +10,7 @@ import (
"github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1"
"github.com/argoproj/argo-cd/v2/test"
"github.com/argoproj/argo-cd/v2/util/argo/diff"
"github.com/argoproj/argo-cd/v2/util/argo/normalizers"
"github.com/argoproj/argo-cd/v2/util/argo/testdata"
)
@@ -22,7 +23,7 @@ func TestNormalize(t *testing.T) {
setup := func(t *testing.T, ignores []v1alpha1.ResourceIgnoreDifferences) *fixture {
t.Helper()
dc, err := diff.NewDiffConfigBuilder().
WithDiffSettings(ignores, nil, true).
WithDiffSettings(ignores, nil, true, normalizers.IgnoreNormalizerOpts{}).
WithNoCache().
Build()
require.NoError(t, err)

View File

@@ -1,9 +1,11 @@
package normalizers
import (
"context"
"encoding/json"
"fmt"
"strings"
"time"
"github.com/argoproj/gitops-engine/pkg/diff"
jsonpatch "github.com/evanphx/json-patch"
@@ -16,6 +18,11 @@ import (
"github.com/argoproj/argo-cd/v2/util/glob"
)
const (
// DefaultJQExecutionTimeout is the maximum time allowed for a JQ patch to execute
DefaultJQExecutionTimeout = 1 * time.Second
)
type normalizerPatch interface {
GetGroupKind() schema.GroupKind
GetNamespace() string
@@ -57,7 +64,8 @@ func (np *jsonPatchNormalizerPatch) Apply(data []byte) ([]byte, error) {
type jqNormalizerPatch struct {
baseNormalizerPatch
code *gojq.Code
code *gojq.Code
jqExecutionTimeout time.Duration
}
func (np *jqNormalizerPatch) Apply(data []byte) ([]byte, error) {
@@ -67,12 +75,18 @@ func (np *jqNormalizerPatch) Apply(data []byte) ([]byte, error) {
return nil, err
}
iter := np.code.Run(dataJson)
ctx, cancel := context.WithTimeout(context.Background(), np.jqExecutionTimeout)
defer cancel()
iter := np.code.RunWithContext(ctx, dataJson)
first, ok := iter.Next()
if !ok {
return nil, fmt.Errorf("JQ patch did not return any data")
}
if err, ok = first.(error); ok {
if err == context.DeadlineExceeded {
return nil, fmt.Errorf("JQ patch execution timed out (%v)", np.jqExecutionTimeout.String())
}
return nil, fmt.Errorf("JQ patch returned error: %w", err)
}
_, ok = iter.Next()
@@ -91,8 +105,19 @@ type ignoreNormalizer struct {
patches []normalizerPatch
}
type IgnoreNormalizerOpts struct {
JQExecutionTimeout time.Duration
}
func (opts *IgnoreNormalizerOpts) getJQExecutionTimeout() time.Duration {
if opts == nil || opts.JQExecutionTimeout == 0 {
return DefaultJQExecutionTimeout
}
return opts.JQExecutionTimeout
}
// NewIgnoreNormalizer creates diff normalizer which removes ignored fields according to given application spec and resource overrides
func NewIgnoreNormalizer(ignore []v1alpha1.ResourceIgnoreDifferences, overrides map[string]v1alpha1.ResourceOverride) (diff.Normalizer, error) {
func NewIgnoreNormalizer(ignore []v1alpha1.ResourceIgnoreDifferences, overrides map[string]v1alpha1.ResourceOverride, opts IgnoreNormalizerOpts) (diff.Normalizer, error) {
for key, override := range overrides {
group, kind, err := getGroupKindForOverrideKey(key)
if err != nil {
@@ -147,7 +172,8 @@ func NewIgnoreNormalizer(ignore []v1alpha1.ResourceIgnoreDifferences, overrides
name: ignore[i].Name,
namespace: ignore[i].Namespace,
},
code: jqDeletionCode,
code: jqDeletionCode,
jqExecutionTimeout: opts.getJQExecutionTimeout(),
})
}
}

View File

@@ -19,7 +19,7 @@ func TestNormalizeObjectWithMatchedGroupKind(t *testing.T) {
Group: "apps",
Kind: "Deployment",
JSONPointers: []string{"/not-matching-path", "/spec/template/spec/containers"},
}}, make(map[string]v1alpha1.ResourceOverride))
}}, make(map[string]v1alpha1.ResourceOverride), IgnoreNormalizerOpts{})
assert.Nil(t, err)
@@ -44,7 +44,7 @@ func TestNormalizeNoMatchedGroupKinds(t *testing.T) {
Group: "",
Kind: "Service",
JSONPointers: []string{"/spec"},
}}, make(map[string]v1alpha1.ResourceOverride))
}}, make(map[string]v1alpha1.ResourceOverride), IgnoreNormalizerOpts{})
assert.Nil(t, err)
@@ -63,7 +63,7 @@ func TestNormalizeMatchedResourceOverrides(t *testing.T) {
"apps/Deployment": {
IgnoreDifferences: v1alpha1.OverrideIgnoreDiff{JSONPointers: []string{"/spec/template/spec/containers"}},
},
})
}, IgnoreNormalizerOpts{})
assert.Nil(t, err)
@@ -118,7 +118,7 @@ func TestNormalizeMissingJsonPointer(t *testing.T) {
"apiextensions.k8s.io/CustomResourceDefinition": {
IgnoreDifferences: v1alpha1.OverrideIgnoreDiff{JSONPointers: []string{"/spec/additionalPrinterColumns/0/priority"}},
},
})
}, IgnoreNormalizerOpts{})
assert.NoError(t, err)
deployment := test.NewDeployment()
@@ -139,7 +139,7 @@ func TestNormalizeGlobMatch(t *testing.T) {
"*/*": {
IgnoreDifferences: v1alpha1.OverrideIgnoreDiff{JSONPointers: []string{"/spec/template/spec/containers"}},
},
})
}, IgnoreNormalizerOpts{})
assert.Nil(t, err)
@@ -161,7 +161,7 @@ func TestNormalizeJQPathExpression(t *testing.T) {
Group: "apps",
Kind: "Deployment",
JQPathExpressions: []string{".spec.template.spec.initContainers[] | select(.name == \"init-container-0\")"},
}}, make(map[string]v1alpha1.ResourceOverride))
}}, make(map[string]v1alpha1.ResourceOverride), IgnoreNormalizerOpts{})
assert.Nil(t, err)
@@ -197,7 +197,7 @@ func TestNormalizeIllegalJQPathExpression(t *testing.T) {
Kind: "Deployment",
JQPathExpressions: []string{".spec.template.spec.containers[] | select(.name == \"missing-quote)"},
// JSONPointers: []string{"no-starting-slash"},
}}, make(map[string]v1alpha1.ResourceOverride))
}}, make(map[string]v1alpha1.ResourceOverride), IgnoreNormalizerOpts{})
assert.Error(t, err)
}
@@ -207,7 +207,7 @@ func TestNormalizeJQPathExpressionWithError(t *testing.T) {
Group: "apps",
Kind: "Deployment",
JQPathExpressions: []string{".spec.fakeField.foo[]"},
}}, make(map[string]v1alpha1.ResourceOverride))
}}, make(map[string]v1alpha1.ResourceOverride), IgnoreNormalizerOpts{})
assert.Nil(t, err)
@@ -230,7 +230,7 @@ func TestNormalizeExpectedErrorAreSilenced(t *testing.T) {
JSONPointers: []string{"/invalid", "/invalid/json/path"},
},
},
})
}, IgnoreNormalizerOpts{})
assert.Nil(t, err)
ignoreNormalizer := normalizer.(*ignoreNormalizer)
@@ -254,12 +254,34 @@ func TestNormalizeExpectedErrorAreSilenced(t *testing.T) {
}
func TestJqPathExpressionFailWithTimeout(t *testing.T) {
normalizer, err := NewIgnoreNormalizer([]v1alpha1.ResourceIgnoreDifferences{}, map[string]v1alpha1.ResourceOverride{
"*/*": {
IgnoreDifferences: v1alpha1.OverrideIgnoreDiff{
JQPathExpressions: []string{"until(true==false; [.] + [1])"},
},
},
}, IgnoreNormalizerOpts{})
assert.Nil(t, err)
ignoreNormalizer := normalizer.(*ignoreNormalizer)
assert.Len(t, ignoreNormalizer.patches, 1)
jqPatch := ignoreNormalizer.patches[0]
deployment := test.NewDeployment()
deploymentData, err := json.Marshal(deployment)
assert.Nil(t, err)
_, err = jqPatch.Apply(deploymentData)
assert.ErrorContains(t, err, "JQ patch execution timed out")
}
func TestJQPathExpressionReturnsHelpfulError(t *testing.T) {
normalizer, err := NewIgnoreNormalizer([]v1alpha1.ResourceIgnoreDifferences{{
Kind: "ConfigMap",
// This is a really wild expression, but it does trigger the desired error.
JQPathExpressions: []string{`.nothing) | .data["config.yaml"] |= (fromjson | del(.auth) | tojson`},
}}, nil)
}}, nil, IgnoreNormalizerOpts{})
assert.NoError(t, err)

View File

@@ -13,7 +13,7 @@ import (
"github.com/argoproj/argo-cd/v2/util/notification/expression/shared"
"github.com/argoproj/notifications-engine/pkg/util/text"
giturls "github.com/whilp/git-urls"
giturls "github.com/chainguard-dev/git-urls"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1"
@@ -33,7 +33,7 @@ func getApplicationSourceAndName(obj *unstructured.Unstructured) (*v1alpha1.Appl
if err != nil {
return nil, "", err
}
return application.Spec.GetSourcePtr(0), application.GetName(), nil
return application.Spec.GetSourcePtrByIndex(0), application.GetName(), nil
}
func getAppDetails(app *unstructured.Unstructured, argocdService service.Service) (*shared.AppDetail, error) {

View File

@@ -135,7 +135,9 @@ func (p *providerImpl) Verify(tokenString string, argoSettings *settings.ArgoCDS
// to avoid logging irrelevant warnings: https://github.com/coreos/go-oidc/pull/406
tokenVerificationErrors[aud] = err
}
if len(tokenVerificationErrors) > 0 {
// If the most recent attempt encountered an error, and if we have collected multiple errors, switch to the
// other error type to gather more context.
if err != nil && len(tokenVerificationErrors) > 0 {
err = tokenVerificationError{errorsByAudience: tokenVerificationErrors}
}
}

View File

@@ -1137,6 +1137,43 @@ allowedAudiences: []`, oidcTestServer.URL),
assert.ErrorIs(t, err, common.TokenVerificationErr)
})
// Make sure the logic works to allow any of the allowed audiences, not just the first one.
t.Run("OIDC provider is external, audience is specified, actual audience isn't the first allowed audience", func(t *testing.T) {
config := map[string]string{
"url": "",
"oidc.config": fmt.Sprintf(`
name: Test
issuer: %s
clientID: xxx
clientSecret: yyy
requestedScopes: ["oidc"]
allowedAudiences: ["aud-a", "aud-b"]`, oidcTestServer.URL),
"oidc.tls.insecure.skip.verify": "true", // This isn't what we're testing.
}
// This is not actually used in the test. The test only calls the OIDC test server. But a valid cert/key pair
// must be set to test VerifyToken's behavior when Argo CD is configured with TLS enabled.
secretConfig := map[string][]byte{
"tls.crt": utiltest.Cert,
"tls.key": utiltest.PrivateKey,
}
settingsMgr := settings.NewSettingsManager(context.Background(), getKubeClientWithConfig(config, secretConfig), "argocd")
mgr := NewSessionManager(settingsMgr, getProjLister(), "", nil, NewUserStateStorage(nil))
mgr.verificationDelayNoiseEnabled = false
claims := jwt.RegisteredClaims{Audience: jwt.ClaimStrings{"aud-b"}, Subject: "admin", ExpiresAt: jwt.NewNumericDate(time.Now().Add(time.Hour * 24))}
claims.Issuer = oidcTestServer.URL
token := jwt.NewWithClaims(jwt.SigningMethodRS512, claims)
key, err := jwt.ParseRSAPrivateKeyFromPEM(utiltest.PrivateKey)
require.NoError(t, err)
tokenString, err := token.SignedString(key)
require.NoError(t, err)
_, _, err = mgr.VerifyToken(tokenString)
assert.NoError(t, err)
})
t.Run("OIDC provider is external, audience is not specified, token is signed with the wrong key", func(t *testing.T) {
config := map[string]string{
"url": "",