From a928e3bc33634fd3711a66e08128deea0aa5ac89 Mon Sep 17 00:00:00 2001 From: Ishita Sequeira <46771830+ishitasequeira@users.noreply.github.com> Date: Fri, 16 Dec 2022 15:47:08 -0500 Subject: [PATCH] feat: Multiple sources for applications (#2789) (#10432) * feat: support multiple sources for application Signed-off-by: ishitasequeira remove debug logging and unwanted code Signed-off-by: ishitasequeira fix lint and unit test errors Signed-off-by: ishitasequeira fix lint and unit test errors Signed-off-by: ishitasequeira * fix bug introduced after rebase Signed-off-by: ishitasequeira executed make codegen Signed-off-by: ishitasequeira * rebase with master Signed-off-by: ishitasequeira remove unwanted logging Signed-off-by: ishitasequeira fix ci failures Signed-off-by: ishitasequeira * fix index out of bounds error Signed-off-by: ishitasequeira * ui fixes Signed-off-by: ishitasequeira Signed-off-by: Michael Crenshaw Signed-off-by: ishitasequeira * add revisions to SyncOperation for rollback Signed-off-by: ishitasequeira * change Source to *ApplicationSource in ApplicationSpec Signed-off-by: ishitasequeira * fix env variable read logic for ValueFiles Signed-off-by: ishitasequeira * update multiple sources doc Signed-off-by: ishitasequeira * add repository lock and checkout target revision Signed-off-by: ishitasequeira fix codegen Signed-off-by: ishitasequeira * checkout all sources before generating manifest Signed-off-by: ishitasequeira generate mock reposerverclient Signed-off-by: ishitasequeira * update logic for returning ManifestResponse to avoid nil pointer issues Signed-off-by: ishitasequeira * fix nil reference and key mismatch bugs; add more logs (#6) * fix nil reference and key mismatch bugs; add more logs * remove temporary comment * addressed the lint failure and added chart to RefTargeRevisionMapping * normalize git repo (#7) * do not leak lock releases * prevent deadlock * allow spec update * move settings fetch outside loop * cache busing * return err instead of logging it * no caching in test * fix cache key marshaling Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Rebase with master Signed-off-by: ishitasequeira * update grpc field numbers Signed-off-by: ishitasequeira * path resolution tests (#12) Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> do things in better ways Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> consolidate Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Signed-off-by: ishitasequeira * add regex check for value of source.ref Signed-off-by: ishitasequeira * add webhook tests Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> change Source to *ApplicationSource in ApplicationSpec Signed-off-by: ishitasequeira address PR comments Signed-off-by: ishitasequeira rebase with master Signed-off-by: ishitasequeira Retrigger CI pipeline Signed-off-by: ishitasequeira rebased with master Signed-off-by: ishitasequeira * fix env variable read logic for ValueFiles Signed-off-by: ishitasequeira Address PR comments Signed-off-by: ishitasequeira * add repository lock and checkout target revision Signed-off-by: ishitasequeira fix codegen Signed-off-by: ishitasequeira * checkout all sources before generating manifest Signed-off-by: ishitasequeira * generate mock reposerverclient Signed-off-by: ishitasequeira * address comments Signed-off-by: ishitasequeira * update logic for returning ManifestResponse to avoid nil pointer issues Signed-off-by: ishitasequeira * fix nil reference and key mismatch bugs; add more logs (#6) * fix nil reference and key mismatch bugs; add more logs * remove temporary comment * addressed the lint failure and added chart to RefTargeRevisionMapping * normalize git repo (#7) * do not leak lock releases * prevent deadlock * allow spec update * move settings fetch outside loop * cache busing * return err instead of logging it * no caching in test * fix cache key marshaling Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Rebase with master Signed-off-by: ishitasequeira * update grpc field numbers Signed-off-by: ishitasequeira * add regex check for value of source.ref Signed-off-by: ishitasequeira * Rebase with master Signed-off-by: ishitasequeira * Added unit tests (#15) * add unit tests 1 * fix lint Signed-off-by: ishitasequeira * fix application parameters tab, rebased UI changes, tests Signed-off-by: ishitasequeira * More tests (#16) * more tests Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> fix lint error Signed-off-by: ishitasequeira Test get ref sources (#17) * test GetRefSources Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> * fix lint Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Signed-off-by: ishitasequeira Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Co-authored-by: ishitasequeira GenerateManifests test (#18) * GenerateManifests test Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Fix broken tests (#19) * fix broken tests Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Symlink test (#20) * check referenced sources for out-of-bounds symlinks Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> * unlock the values file repo before doing a symlink check (#22) Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> * multi source docs (#21) * multi source docs Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> * fix warning title Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> * clarify Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> * clarify Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> * add e2e tests for multiple sources and fix UI lint (#23) * add e2e tests for multiple sources and fix UI lint Signed-off-by: ishitasequeira * add auto-sync and hard refresh to e2e tests Signed-off-by: ishitasequeira * change refresh type to RefreshTypeNormal for e2e Signed-off-by: ishitasequeira * update e2e testcase with helm data Signed-off-by: ishitasequeira * add TestMultiSourceAppWithSourceOverride Signed-off-by: ishitasequeira * add missing yaml file Signed-off-by: ishitasequeira Signed-off-by: ishitasequeira * rebase with master Signed-off-by: ishitasequeira * rebase with master Signed-off-by: ishitasequeira * fix lint Signed-off-by: ishitasequeira Signed-off-by: ishitasequeira Signed-off-by: Michael Crenshaw Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Co-authored-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Signed-off-by: schakrad --- .../applicationset_controller_test.go | 28 +- applicationset/utils/utils_test.go | 6 +- assets/swagger.json | 74 + cmd/argocd/commands/admin/app.go | 7 +- cmd/argocd/commands/admin/app_test.go | 1 + cmd/argocd/commands/app.go | 90 +- cmd/argocd/commands/app_test.go | 8 +- cmd/argocd/commands/applicationset.go | 13 +- cmd/util/app.go | 93 +- cmd/util/app_test.go | 4 +- controller/appcontroller.go | 142 +- controller/appcontroller_test.go | 6 +- controller/metrics/metrics.go | 2 +- controller/state.go | 253 +- controller/state_test.go | 132 +- controller/sync.go | 64 +- controller/sync_test.go | 4 +- docs/operator-manual/application.yaml | 7 + docs/user-guide/multiple_sources.md | 73 + .../generators/application_generator.go | 2 +- manifests/core-install.yaml | 6455 +++++++++++++++-- manifests/crds/application-crd.yaml | 1899 ++++- manifests/crds/applicationset-crd.yaml | 3550 ++++++++- manifests/ha/install.yaml | 6455 +++++++++++++++-- manifests/install.yaml | 6455 +++++++++++++++-- mkdocs.yml | 1 + pkg/apis/api-rules/violation_exceptions.list | 8 + pkg/apis/application/v1alpha1/generated.pb.go | 2143 ++++-- pkg/apis/application/v1alpha1/generated.proto | 43 + .../application/v1alpha1/openapi_generated.go | 196 +- pkg/apis/application/v1alpha1/types.go | 77 +- pkg/apis/application/v1alpha1/types_test.go | 80 + .../v1alpha1/zz_generated.deepcopy.go | 135 +- .../mocks/RepoServerServiceClient.go | 2 +- reposerver/apiclient/repository.pb.go | 675 +- reposerver/cache/cache.go | 78 +- reposerver/cache/cache_test.go | 66 +- reposerver/repository/repository.go | 294 +- reposerver/repository/repository.proto | 3 + reposerver/repository/repository_test.go | 314 +- server/application/application.go | 111 +- server/application/application_test.go | 11 +- server/extension/extension_test.go | 17 +- server/project/project.go | 4 +- server/project/project_test.go | 14 +- server/repository/repository.go | 3 +- server/repository/repository_test.go | 6 +- test/e2e/app_autosync_test.go | 3 +- test/e2e/app_management_ns_test.go | 19 +- test/e2e/app_management_test.go | 18 +- test/e2e/app_multiple_sources_test.go | 165 + test/e2e/app_namespaces_test.go | 6 +- test/e2e/applicationset_test.go | 60 +- test/e2e/cluster_generator_test.go | 16 +- test/e2e/clusterdecisiongenerator_e2e_test.go | 16 +- test/e2e/custom_tool_test.go | 2 +- test/e2e/fixture/app/actions.go | 47 +- test/e2e/fixture/app/context.go | 6 + .../fixture/applicationsets/expectation.go | 8 +- test/e2e/helm_test.go | 36 +- test/e2e/kustomize_test.go | 12 +- test/e2e/matrix_e2e_test.go | 8 +- test/e2e/merge_e2e_test.go | 8 +- test/e2e/project_management_test.go | 2 +- .../multiple-source-values/pod-1.yaml | 14 + .../multiple-source-values/values.yaml | 1 + .../application-create-panel.tsx | 17 +- .../application-details.tsx | 6 +- .../application-operation-state.tsx | 2 +- .../application-parameters.tsx | 38 +- .../application-status-panel.tsx | 15 +- .../application-summary.tsx | 27 +- .../application-sync-panel.tsx | 7 +- .../applications-list/applications-filter.tsx | 4 +- .../applications-list/applications-labels.tsx | 3 +- .../applications-list/applications-table.tsx | 4 +- .../applications-list/applications-tiles.tsx | 353 +- .../applications-sync-panel.tsx | 4 +- .../resource-details/resource-details.tsx | 4 +- ui/src/app/applications/components/utils.tsx | 36 +- ui/src/app/shared/models.ts | 4 + util/argo/argo.go | 385 +- util/argo/argo_test.go | 263 +- util/helm/client.go | 6 +- util/io/mocks/TempPaths.go | 65 + util/io/paths.go | 28 +- util/io/paths_test.go | 22 +- util/notification/expression/repo/repo.go | 2 +- util/webhook/webhook.go | 64 +- util/webhook/webhook_test.go | 226 +- 90 files changed, 27950 insertions(+), 4186 deletions(-) create mode 100644 docs/user-guide/multiple_sources.md create mode 100644 test/e2e/app_multiple_sources_test.go create mode 100644 test/e2e/testdata/multiple-source-values/pod-1.yaml create mode 100644 test/e2e/testdata/multiple-source-values/values.yaml create mode 100644 util/io/mocks/TempPaths.go diff --git a/applicationset/controllers/applicationset_controller_test.go b/applicationset/controllers/applicationset_controller_test.go index 4a45da8f42efc..852c1da0c91d6 100644 --- a/applicationset/controllers/applicationset_controller_test.go +++ b/applicationset/controllers/applicationset_controller_test.go @@ -684,7 +684,7 @@ func TestCreateOrUpdateInCluster(t *testing.T) { Template: argov1alpha1.ApplicationSetTemplate{ Spec: argov1alpha1.ApplicationSpec{ Project: "project", - Source: argov1alpha1.ApplicationSource{Path: "path", TargetRevision: "revision", RepoURL: "repoURL"}, + Source: &argov1alpha1.ApplicationSource{Path: "path", TargetRevision: "revision", RepoURL: "repoURL"}, Destination: argov1alpha1.ApplicationDestination{Server: "server", Namespace: "namespace"}, }, }, @@ -721,7 +721,7 @@ func TestCreateOrUpdateInCluster(t *testing.T) { }, Spec: argov1alpha1.ApplicationSpec{ Project: "project", - Source: argov1alpha1.ApplicationSource{Path: "path", TargetRevision: "revision", RepoURL: "repoURL"}, + Source: &argov1alpha1.ApplicationSource{Path: "path", TargetRevision: "revision", RepoURL: "repoURL"}, Destination: argov1alpha1.ApplicationDestination{Server: "server", Namespace: "namespace"}, }, }, @@ -741,7 +741,7 @@ func TestCreateOrUpdateInCluster(t *testing.T) { }, Spec: argov1alpha1.ApplicationSpec{ Project: "project", - Source: argov1alpha1.ApplicationSource{Path: "path", TargetRevision: "revision", RepoURL: "repoURL"}, + Source: &argov1alpha1.ApplicationSource{Path: "path", TargetRevision: "revision", RepoURL: "repoURL"}, Destination: argov1alpha1.ApplicationDestination{Server: "server", Namespace: "namespace"}, }, Status: argov1alpha1.ApplicationStatus{ @@ -918,7 +918,7 @@ func TestRemoveFinalizerOnInvalidDestination_FinalizerTypes(t *testing.T) { }, Spec: argov1alpha1.ApplicationSpec{ Project: "project", - Source: argov1alpha1.ApplicationSource{Path: "path", TargetRevision: "revision", RepoURL: "repoURL"}, + Source: &argov1alpha1.ApplicationSource{Path: "path", TargetRevision: "revision", RepoURL: "repoURL"}, // Destination is always invalid, for this test: Destination: argov1alpha1.ApplicationDestination{Name: "my-cluster", Namespace: "namespace"}, }, @@ -1080,7 +1080,7 @@ func TestRemoveFinalizerOnInvalidDestination_DestinationTypes(t *testing.T) { }, Spec: argov1alpha1.ApplicationSpec{ Project: "project", - Source: argov1alpha1.ApplicationSource{Path: "path", TargetRevision: "revision", RepoURL: "repoURL"}, + Source: &argov1alpha1.ApplicationSource{Path: "path", TargetRevision: "revision", RepoURL: "repoURL"}, Destination: c.destinationField, }, } @@ -1589,7 +1589,7 @@ func TestValidateGeneratedApplications(t *testing.T) { ObjectMeta: metav1.ObjectMeta{}, Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: argov1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://url", Path: "/", TargetRevision: "HEAD", @@ -1612,7 +1612,7 @@ func TestValidateGeneratedApplications(t *testing.T) { ObjectMeta: metav1.ObjectMeta{}, Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: argov1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://url", Path: "/", TargetRevision: "HEAD", @@ -1636,7 +1636,7 @@ func TestValidateGeneratedApplications(t *testing.T) { ObjectMeta: metav1.ObjectMeta{}, Spec: argov1alpha1.ApplicationSpec{ Project: "DOES-NOT-EXIST", - Source: argov1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://url", Path: "/", TargetRevision: "HEAD", @@ -1659,7 +1659,7 @@ func TestValidateGeneratedApplications(t *testing.T) { ObjectMeta: metav1.ObjectMeta{}, Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: argov1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://url", Path: "/", TargetRevision: "HEAD", @@ -1682,7 +1682,7 @@ func TestValidateGeneratedApplications(t *testing.T) { ObjectMeta: metav1.ObjectMeta{}, Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: argov1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://url", Path: "/", TargetRevision: "HEAD", @@ -1811,7 +1811,7 @@ func TestReconcilerValidationErrorBehaviour(t *testing.T) { Namespace: "argocd", }, Spec: argov1alpha1.ApplicationSpec{ - Source: argov1alpha1.ApplicationSource{RepoURL: "https://github.com/argoproj/argocd-example-apps", Path: "guestbook"}, + Source: &argov1alpha1.ApplicationSource{RepoURL: "https://github.com/argoproj/argocd-example-apps", Path: "guestbook"}, Project: "default", Destination: argov1alpha1.ApplicationDestination{Server: "{{.url}}"}, }, @@ -1954,7 +1954,7 @@ func TestGenerateAppsUsingPullRequestGenerator(t *testing.T) { }, }, Spec: argov1alpha1.ApplicationSpec{ - Source: argov1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://testurl/testRepo", TargetRevision: "{{.head_short_sha}}", }, @@ -1973,7 +1973,7 @@ func TestGenerateAppsUsingPullRequestGenerator(t *testing.T) { }, }, Spec: v1alpha1.ApplicationSpec{ - Source: v1alpha1.ApplicationSource{ + Source: &v1alpha1.ApplicationSource{ RepoURL: "https://testurl/testRepo", TargetRevision: "089d92cb", }, @@ -2113,7 +2113,7 @@ func TestPolicies(t *testing.T) { }, }, Spec: argov1alpha1.ApplicationSpec{ - Source: argov1alpha1.ApplicationSource{RepoURL: "https://github.com/argoproj/argocd-example-apps", Path: "guestbook"}, + Source: &argov1alpha1.ApplicationSource{RepoURL: "https://github.com/argoproj/argocd-example-apps", Path: "guestbook"}, Project: "default", Destination: argov1alpha1.ApplicationDestination{Server: "https://kubernetes.default.svc"}, }, diff --git a/applicationset/utils/utils_test.go b/applicationset/utils/utils_test.go index 38c6aee2bf1f1..af36c18a39dbb 100644 --- a/applicationset/utils/utils_test.go +++ b/applicationset/utils/utils_test.go @@ -41,7 +41,7 @@ func TestRenderTemplateParams(t *testing.T) { Namespace: "default", }, Spec: argoappsv1.ApplicationSpec{ - Source: argoappsv1.ApplicationSource{ + Source: &argoappsv1.ApplicationSource{ Path: "", RepoURL: "", TargetRevision: "", @@ -220,7 +220,7 @@ func TestRenderTemplateParamsGoTemplate(t *testing.T) { Namespace: "default", }, Spec: argoappsv1.ApplicationSpec{ - Source: argoappsv1.ApplicationSource{ + Source: &argoappsv1.ApplicationSource{ Path: "", RepoURL: "", TargetRevision: "", @@ -511,7 +511,7 @@ func TestRenderTemplateParamsFinalizers(t *testing.T) { emptyApplication := &argoappsv1.Application{ Spec: argoappsv1.ApplicationSpec{ - Source: argoappsv1.ApplicationSource{ + Source: &argoappsv1.ApplicationSource{ Path: "", RepoURL: "", TargetRevision: "", diff --git a/assets/swagger.json b/assets/swagger.json index 9ca58c841af1a..fc3874d20bc45 100644 --- a/assets/swagger.json +++ b/assets/swagger.json @@ -5831,6 +5831,10 @@ "plugin": { "$ref": "#/definitions/v1alpha1ApplicationSourcePlugin" }, + "ref": { + "description": "Ref is reference to another source within sources field. This field will not be used if used with a `source` tag.", + "type": "string" + }, "repoURL": { "type": "string", "title": "RepoURL is the URL to the repository (Git or Helm) that contains the application manifests" @@ -6068,6 +6072,13 @@ "source": { "$ref": "#/definitions/v1alpha1ApplicationSource" }, + "sources": { + "type": "array", + "title": "Sources is a reference to the location of the application's manifests or chart", + "items": { + "$ref": "#/definitions/v1alpha1ApplicationSource" + } + }, "syncPolicy": { "$ref": "#/definitions/v1alpha1SyncPolicy" } @@ -6118,6 +6129,13 @@ "type": "string", "title": "SourceType specifies the type of this application" }, + "sourceTypes": { + "type": "array", + "title": "SourceTypes specifies the type of the sources included in the application", + "items": { + "type": "string" + } + }, "summary": { "$ref": "#/definitions/v1alpha1ApplicationSummary" }, @@ -6415,6 +6433,13 @@ }, "source": { "$ref": "#/definitions/v1alpha1ApplicationSource" + }, + "sources": { + "type": "array", + "title": "Sources is a reference to the application's multiple sources used for comparison", + "items": { + "$ref": "#/definitions/v1alpha1ApplicationSource" + } } } }, @@ -7757,8 +7782,22 @@ "type": "string", "title": "Revision holds the revision the sync was performed against" }, + "revisions": { + "type": "array", + "title": "Revisions holds the revision of each source in sources field the sync was performed against", + "items": { + "type": "string" + } + }, "source": { "$ref": "#/definitions/v1alpha1ApplicationSource" + }, + "sources": { + "type": "array", + "title": "Sources is a reference to the application sources used for the sync operation", + "items": { + "$ref": "#/definitions/v1alpha1ApplicationSource" + } } } }, @@ -8059,9 +8098,23 @@ "description": "Revision is the revision (Git) or chart version (Helm) which to sync the application to\nIf omitted, will use the revision specified in app spec.", "type": "string" }, + "revisions": { + "description": "Revisions is the list of revision (Git) or chart version (Helm) which to sync each source in sources field for the application to\nIf omitted, will use the revision specified in app spec.", + "type": "array", + "items": { + "type": "string" + } + }, "source": { "$ref": "#/definitions/v1alpha1ApplicationSource" }, + "sources": { + "type": "array", + "title": "Sources overrides the source definition set in the application.\nThis is typically set in a Rollback operation and is nil during a Sync operation", + "items": { + "$ref": "#/definitions/v1alpha1ApplicationSource" + } + }, "syncOptions": { "type": "array", "title": "SyncOptions provide per-sync sync-options, e.g. Validate=false", @@ -8107,8 +8160,22 @@ "type": "string", "title": "Revision holds the revision this sync operation was performed to" }, + "revisions": { + "type": "array", + "title": "Revisions holds the revision this sync operation was performed for respective indexed source in sources field", + "items": { + "type": "string" + } + }, "source": { "$ref": "#/definitions/v1alpha1ApplicationSource" + }, + "sources": { + "type": "array", + "title": "Source records the application source information of the sync, used for comparing auto-sync", + "items": { + "$ref": "#/definitions/v1alpha1ApplicationSource" + } } } }, @@ -8163,6 +8230,13 @@ "type": "string", "title": "Revision contains information about the revision the comparison has been performed to" }, + "revisions": { + "type": "array", + "title": "Revisions contains information about the revisions of multiple sources the comparison has been performed to", + "items": { + "type": "string" + } + }, "status": { "type": "string", "title": "Status is the sync state of the comparison" diff --git a/cmd/argocd/commands/admin/app.go b/cmd/argocd/commands/admin/app.go index f65717e692ec4..e2e2103e75439 100644 --- a/cmd/argocd/commands/admin/app.go +++ b/cmd/argocd/commands/admin/app.go @@ -401,7 +401,12 @@ func reconcileApplications( return nil, err } - res := appStateManager.CompareAppState(&app, proj, app.Spec.Source.TargetRevision, app.Spec.Source, false, false, nil) + sources := make([]v1alpha1.ApplicationSource, 0) + revisions := make([]string, 0) + sources = append(sources, app.Spec.GetSource()) + revisions = append(revisions, app.Spec.GetSource().TargetRevision) + + res := appStateManager.CompareAppState(&app, proj, revisions, sources, false, false, nil, false) items = append(items, appReconcileResult{ Name: app.Name, Conditions: app.Status.Conditions, diff --git a/cmd/argocd/commands/admin/app_test.go b/cmd/argocd/commands/admin/app_test.go index dbb0bd245915d..0cad2485e6696 100644 --- a/cmd/argocd/commands/admin/app_test.go +++ b/cmd/argocd/commands/admin/app_test.go @@ -80,6 +80,7 @@ func TestGetReconcileResults_Refresh(t *testing.T) { Namespace: "default", }, Spec: v1alpha1.ApplicationSpec{ + Source: &v1alpha1.ApplicationSource{}, Project: "default", Destination: v1alpha1.ApplicationDestination{ Server: v1alpha1.KubernetesInternalAPIServerAddr, diff --git a/cmd/argocd/commands/app.go b/cmd/argocd/commands/app.go index 9f7cfeafda4f4..28e070e5da0c6 100644 --- a/cmd/argocd/commands/app.go +++ b/cmd/argocd/commands/app.go @@ -150,7 +150,7 @@ func NewApplicationCreateCommand(clientOpts *argocdclient.ClientOptions) *cobra. c.HelpFunc()(c, args) os.Exit(1) } - if app.Spec.Source.Plugin != nil && app.Spec.Source.Plugin.Name != "" { + if app.Spec.GetSource().Plugin != nil && app.Spec.GetSource().Plugin.Name != "" { log.Warnf(argocommon.ConfigMapPluginCLIDeprecationWarning) } if appNamespace != "" { @@ -294,7 +294,7 @@ func NewApplicationGetCommand(clientOpts *argocdclient.ClientOptions) *cobra.Com }) errors.CheckError(err) - if app.Spec.Source.Plugin != nil && app.Spec.Source.Plugin.Name != "" { + if app.Spec.GetSource().Plugin != nil && app.Spec.GetSource().Plugin.Name != "" { log.Warnf(argocommon.ConfigMapPluginCLIDeprecationWarning) } @@ -440,15 +440,16 @@ func NewApplicationLogsCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co } func printAppSummaryTable(app *argoappv1.Application, appURL string, windows *argoappv1.SyncWindows) { + source := app.Spec.GetSource() fmt.Printf(printOpFmtStr, "Name:", app.QualifiedName()) fmt.Printf(printOpFmtStr, "Project:", app.Spec.GetProject()) fmt.Printf(printOpFmtStr, "Server:", getServer(app)) fmt.Printf(printOpFmtStr, "Namespace:", app.Spec.Destination.Namespace) fmt.Printf(printOpFmtStr, "URL:", appURL) - fmt.Printf(printOpFmtStr, "Repo:", app.Spec.Source.RepoURL) - fmt.Printf(printOpFmtStr, "Target:", app.Spec.Source.TargetRevision) - fmt.Printf(printOpFmtStr, "Path:", app.Spec.Source.Path) - printAppSourceDetails(&app.Spec.Source) + fmt.Printf(printOpFmtStr, "Repo:", source.RepoURL) + fmt.Printf(printOpFmtStr, "Target:", source.TargetRevision) + fmt.Printf(printOpFmtStr, "Path:", source.Path) + printAppSourceDetails(&source) var wds []string var status string var allow, deny, inactiveAllows bool @@ -502,11 +503,11 @@ func printAppSummaryTable(app *argoappv1.Application, appURL string, windows *ar syncStatusStr := string(app.Status.Sync.Status) switch app.Status.Sync.Status { case argoappv1.SyncStatusCodeSynced: - syncStatusStr += fmt.Sprintf(" to %s", app.Spec.Source.TargetRevision) + syncStatusStr += fmt.Sprintf(" to %s", app.Spec.GetSource().TargetRevision) case argoappv1.SyncStatusCodeOutOfSync: - syncStatusStr += fmt.Sprintf(" from %s", app.Spec.Source.TargetRevision) + syncStatusStr += fmt.Sprintf(" from %s", app.Spec.GetSource().TargetRevision) } - if !git.IsCommitSHA(app.Spec.Source.TargetRevision) && !git.IsTruncatedCommitSHA(app.Spec.Source.TargetRevision) && len(app.Status.Sync.Revision) > 7 { + if !git.IsCommitSHA(app.Spec.GetSource().TargetRevision) && !git.IsTruncatedCommitSHA(app.Spec.GetSource().TargetRevision) && len(app.Status.Sync.Revision) > 7 { syncStatusStr += fmt.Sprintf(" (%s)", app.Status.Sync.Revision[0:7]) } fmt.Printf(printOpFmtStr, "Sync Status:", syncStatusStr) @@ -575,8 +576,8 @@ func truncateString(str string, num int) string { // printParams prints parameters and overrides func printParams(app *argoappv1.Application) { - if app.Spec.Source.Helm != nil { - printHelmParams(app.Spec.Source.Helm) + if app.Spec.GetSource().Helm != nil { + printHelmParams(app.Spec.GetSource().Helm) } } @@ -624,7 +625,7 @@ func NewApplicationSetCommand(clientOpts *argocdclient.ClientOptions) *cobra.Com app, err := appIf.Get(ctx, &applicationpkg.ApplicationQuery{Name: &appName, AppNamespace: &appNs}) errors.CheckError(err) - if app.Spec.Source.Plugin != nil && app.Spec.Source.Plugin.Name != "" { + if app.Spec.GetSource().Plugin != nil && app.Spec.GetSource().Plugin.Name != "" { log.Warnf(argocommon.ConfigMapPluginCLIDeprecationWarning) } @@ -692,11 +693,12 @@ func NewApplicationUnsetCommand(clientOpts *argocdclient.ClientOptions) *cobra.C app, err := appIf.Get(ctx, &applicationpkg.ApplicationQuery{Name: &appName, AppNamespace: &appNs}) errors.CheckError(err) - if app.Spec.Source.Plugin != nil && app.Spec.Source.Plugin.Name != "" { + if app.Spec.GetSource().Plugin != nil && app.Spec.GetSource().Plugin.Name != "" { log.Warnf(argocommon.ConfigMapPluginCLIDeprecationWarning) } - updated, nothingToUnset := unset(&app.Spec.Source, opts) + source := app.Spec.GetSource() + updated, nothingToUnset := unset(&source, opts) if nothingToUnset { c.HelpFunc()(c, args) os.Exit(1) @@ -842,18 +844,19 @@ func getLocalObjects(ctx context.Context, app *argoappv1.Application, local, loc func getLocalObjectsString(ctx context.Context, app *argoappv1.Application, local, localRepoRoot, appLabelKey, kubeVersion string, apiVersions []string, kustomizeOptions *argoappv1.KustomizeOptions, configManagementPlugins []*argoappv1.ConfigManagementPlugin, trackingMethod string) []string { - res, err := repository.GenerateManifests(ctx, local, localRepoRoot, app.Spec.Source.TargetRevision, &repoapiclient.ManifestRequest{ - Repo: &argoappv1.Repository{Repo: app.Spec.Source.RepoURL}, + source := app.Spec.GetSource() + res, err := repository.GenerateManifests(ctx, local, localRepoRoot, source.TargetRevision, &repoapiclient.ManifestRequest{ + Repo: &argoappv1.Repository{Repo: source.RepoURL}, AppLabelKey: appLabelKey, AppName: app.Name, Namespace: app.Spec.Destination.Namespace, - ApplicationSource: &app.Spec.Source, + ApplicationSource: &source, KustomizeOptions: kustomizeOptions, KubeVersion: kubeVersion, ApiVersions: apiVersions, Plugins: configManagementPlugins, TrackingMethod: trackingMethod, - }, true, &git.NoopCredsStore{}, resource.MustParse("0")) + }, true, &git.NoopCredsStore{}, resource.MustParse("0"), nil) errors.CheckError(err) return res.Manifests @@ -930,7 +933,7 @@ func NewApplicationDiffCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co }) errors.CheckError(err) - if app.Spec.Source.Plugin != nil && app.Spec.Source.Plugin.Name != "" { + if app.Spec.GetSource().Plugin != nil && app.Spec.GetSource().Plugin.Name != "" { log.Warnf(argocommon.ConfigMapPluginCLIDeprecationWarning) } @@ -1247,7 +1250,7 @@ func printApplicationTable(apps []argoappv1.Application, output *string) { formatConditionsSummary(app), } if *output == "wide" { - vals = append(vals, app.Spec.Source.RepoURL, app.Spec.Source.Path, app.Spec.Source.TargetRevision) + vals = append(vals, app.Spec.GetSource().RepoURL, app.Spec.GetSource().Path, app.Spec.GetSource().TargetRevision) } _, _ = fmt.Fprintf(w, fmtStr, vals...) } @@ -1300,7 +1303,7 @@ func NewApplicationListCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co } var appsWithDeprecatedPlugins []string for _, app := range appList { - if app.Spec.Source.Plugin != nil && app.Spec.Source.Plugin.Name != "" { + if app.Spec.GetSource().Plugin != nil && app.Spec.GetSource().Plugin.Name != "" { appsWithDeprecatedPlugins = append(appsWithDeprecatedPlugins, app.Name) } } @@ -1625,14 +1628,20 @@ func NewApplicationSyncCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co var localObjsStrings []string diffOption := &DifferenceOption{} - if local != "" { - app, err := appIf.Get(ctx, &applicationpkg.ApplicationQuery{ - Name: &appName, - AppNamespace: &appNs, - }) - errors.CheckError(err) - if app.Spec.Source.Plugin != nil && app.Spec.Source.Plugin.Name != "" { + app, err := appIf.Get(ctx, &applicationpkg.ApplicationQuery{ + Name: &appName, + AppNamespace: &appNs, + }) + errors.CheckError(err) + + if app.Spec.HasMultipleSources() { + log.Fatal("argocd cli does not work on multi-source app") + return + } + + if local != "" { + if app.Spec.GetSource().Plugin != nil && app.Spec.GetSource().Plugin.Name != "" { log.Warnf(argocommon.ConfigMapPluginCLIDeprecationWarning) } @@ -1709,13 +1718,7 @@ func NewApplicationSyncCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co } } if diffChanges { - app, err := appIf.Get(ctx, &applicationpkg.ApplicationQuery{ - Name: &appName, - AppNamespace: &appNs, - }) - errors.CheckError(err) - - if app.Spec.Source.Plugin != nil && app.Spec.Source.Plugin.Name != "" { + if app.Spec.GetSource().Plugin != nil && app.Spec.GetSource().Plugin.Name != "" { log.Warnf(argocommon.ConfigMapPluginCLIDeprecationWarning) } @@ -2087,8 +2090,9 @@ func setParameterOverrides(app *argoappv1.Application, parameters []string) { if len(parameters) == 0 { return } + source := app.Spec.GetSource() var sourceType argoappv1.ApplicationSourceType - if st, _ := app.Spec.Source.ExplicitType(); st != nil { + if st, _ := source.ExplicitType(); st != nil { sourceType = *st } else if app.Status.SourceType != "" { sourceType = app.Status.SourceType @@ -2100,8 +2104,8 @@ func setParameterOverrides(app *argoappv1.Application, parameters []string) { switch sourceType { case argoappv1.ApplicationSourceTypeHelm: - if app.Spec.Source.Helm == nil { - app.Spec.Source.Helm = &argoappv1.ApplicationSourceHelm{} + if source.Helm == nil { + source.Helm = &argoappv1.ApplicationSourceHelm{} } for _, p := range parameters { newParam, err := argoappv1.NewHelmParameter(p, false) @@ -2109,7 +2113,7 @@ func setParameterOverrides(app *argoappv1.Application, parameters []string) { log.Error(err) continue } - app.Spec.Source.Helm.AddParameter(*newParam) + source.Helm.AddParameter(*newParam) } default: log.Fatalf("Parameters can only be set against Helm applications") @@ -2161,7 +2165,7 @@ func NewApplicationHistoryCommand(clientOpts *argocdclient.ClientOptions) *cobra }) errors.CheckError(err) - if app.Spec.Source.Plugin != nil && app.Spec.Source.Plugin.Name != "" { + if app.Spec.GetSource().Plugin != nil && app.Spec.GetSource().Plugin.Name != "" { log.Warnf(argocommon.ConfigMapPluginCLIDeprecationWarning) } @@ -2225,7 +2229,7 @@ func NewApplicationRollbackCommand(clientOpts *argocdclient.ClientOptions) *cobr }) errors.CheckError(err) - if app.Spec.Source.Plugin != nil && app.Spec.Source.Plugin.Name != "" { + if app.Spec.GetSource().Plugin != nil && app.Spec.GetSource().Plugin.Name != "" { log.Warnf(argocommon.ConfigMapPluginCLIDeprecationWarning) } @@ -2312,7 +2316,7 @@ func NewApplicationManifestsCommand(clientOpts *argocdclient.ClientOptions) *cob app, err := appIf.Get(context.Background(), &applicationpkg.ApplicationQuery{Name: &appName}) errors.CheckError(err) - if app.Spec.Source.Plugin != nil && app.Spec.Source.Plugin.Name != "" { + if app.Spec.GetSource().Plugin != nil && app.Spec.GetSource().Plugin.Name != "" { log.Warnf(argocommon.ConfigMapPluginCLIDeprecationWarning) } @@ -2415,7 +2419,7 @@ func NewApplicationEditCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co }) errors.CheckError(err) - if app.Spec.Source.Plugin != nil && app.Spec.Source.Plugin.Name != "" { + if app.Spec.GetSource().Plugin != nil && app.Spec.GetSource().Plugin.Name != "" { log.Warnf(argocommon.ConfigMapPluginCLIDeprecationWarning) } diff --git a/cmd/argocd/commands/app_test.go b/cmd/argocd/commands/app_test.go index 1d3d3d6134ac4..d5ae6fcb5e500 100644 --- a/cmd/argocd/commands/app_test.go +++ b/cmd/argocd/commands/app_test.go @@ -498,7 +498,7 @@ func TestPrintAppSummaryTable(t *testing.T) { }, Project: "default", Destination: v1alpha1.ApplicationDestination{Server: "local", Namespace: "argocd"}, - Source: v1alpha1.ApplicationSource{ + Source: &v1alpha1.ApplicationSource{ RepoURL: "test", TargetRevision: "master", Path: "/test", @@ -604,7 +604,7 @@ func TestPrintParams(t *testing.T) { output, _ := captureOutput(func() error { app := &v1alpha1.Application{ Spec: v1alpha1.ApplicationSpec{ - Source: v1alpha1.ApplicationSource{ + Source: &v1alpha1.ApplicationSource{ Helm: &v1alpha1.ApplicationSourceHelm{ Parameters: []v1alpha1.HelmParameter{ { @@ -985,7 +985,7 @@ func TestPrintApplicationTableWide(t *testing.T) { Server: "http://localhost:8080", Namespace: "default", }, - Source: v1alpha1.ApplicationSource{ + Source: &v1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps", Path: "guestbook", TargetRevision: "123", @@ -1261,7 +1261,7 @@ func testApp(name, project string, labels map[string]string, annotations map[str Finalizers: finalizers, }, Spec: argoappv1.ApplicationSpec{ - Source: argoappv1.ApplicationSource{ + Source: &argoappv1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", }, Project: project, diff --git a/cmd/argocd/commands/applicationset.go b/cmd/argocd/commands/applicationset.go index 5fa3809fe95d5..678d5699b9d19 100644 --- a/cmd/argocd/commands/applicationset.go +++ b/cmd/argocd/commands/applicationset.go @@ -95,7 +95,7 @@ func NewApplicationSetGetCommand(clientOpts *argocdclient.ClientOptions) *cobra. fmt.Println() } if showParams { - printHelmParams(appSet.Spec.Template.Spec.Source.Helm) + printHelmParams(appSet.Spec.Template.Spec.GetSource().Helm) } default: errors.CheckError(fmt.Errorf("unknown output format: %s", output)) @@ -317,7 +317,7 @@ func printApplicationSetTable(apps []arogappsetv1.ApplicationSet, output *string conditions, } if *output == "wide" { - vals = append(vals, app.Spec.Template.Spec.Source.RepoURL, app.Spec.Template.Spec.Source.Path, app.Spec.Template.Spec.Source.TargetRevision) + vals = append(vals, app.Spec.Template.Spec.GetSource().RepoURL, app.Spec.Template.Spec.GetSource().Path, app.Spec.Template.Spec.GetSource().TargetRevision) } _, _ = fmt.Fprintf(w, fmtStr, vals...) } @@ -333,14 +333,15 @@ func getServerForAppSet(appSet *arogappsetv1.ApplicationSet) string { } func printAppSetSummaryTable(appSet *arogappsetv1.ApplicationSet) { + source := appSet.Spec.Template.Spec.GetSource() fmt.Printf(printOpFmtStr, "Name:", appSet.Name) fmt.Printf(printOpFmtStr, "Project:", appSet.Spec.Template.Spec.GetProject()) fmt.Printf(printOpFmtStr, "Server:", getServerForAppSet(appSet)) fmt.Printf(printOpFmtStr, "Namespace:", appSet.Spec.Template.Spec.Destination.Namespace) - fmt.Printf(printOpFmtStr, "Repo:", appSet.Spec.Template.Spec.Source.RepoURL) - fmt.Printf(printOpFmtStr, "Target:", appSet.Spec.Template.Spec.Source.TargetRevision) - fmt.Printf(printOpFmtStr, "Path:", appSet.Spec.Template.Spec.Source.Path) - printAppSourceDetails(&appSet.Spec.Template.Spec.Source) + fmt.Printf(printOpFmtStr, "Repo:", source.RepoURL) + fmt.Printf(printOpFmtStr, "Target:", source.TargetRevision) + fmt.Printf(printOpFmtStr, "Path:", source.Path) + printAppSourceDetails(&source) var syncPolicy string if appSet.Spec.SyncPolicy != nil && appSet.Spec.Template.Spec.SyncPolicy.Automated != nil { diff --git a/cmd/util/app.go b/cmd/util/app.go index baa7238665c12..e80950533b054 100644 --- a/cmd/util/app.go +++ b/cmd/util/app.go @@ -138,22 +138,26 @@ func SetAppSpecOptions(flags *pflag.FlagSet, spec *argoappv1.ApplicationSpec, ap } flags.Visit(func(f *pflag.Flag) { visited++ + source := spec.GetSourcePtr() + if source == nil { + source = &argoappv1.ApplicationSource{} + } switch f.Name { case "repo": - spec.Source.RepoURL = appOpts.repoURL + source.RepoURL = appOpts.repoURL case "path": - spec.Source.Path = appOpts.appPath + source.Path = appOpts.appPath case "helm-chart": - spec.Source.Chart = appOpts.chart + source.Chart = appOpts.chart case "revision": - spec.Source.TargetRevision = appOpts.revision + source.TargetRevision = appOpts.revision case "revision-history-limit": i := int64(appOpts.revisionHistoryLimit) spec.RevisionHistoryLimit = &i case "values": - setHelmOpt(&spec.Source, helmOpts{valueFiles: appOpts.valuesFiles}) + setHelmOpt(source, helmOpts{valueFiles: appOpts.valuesFiles}) case "ignore-missing-value-files": - setHelmOpt(&spec.Source, helmOpts{ignoreMissingValueFiles: appOpts.ignoreMissingValueFiles}) + setHelmOpt(source, helmOpts{ignoreMissingValueFiles: appOpts.ignoreMissingValueFiles}) case "values-literal-file": var data []byte @@ -165,41 +169,41 @@ func SetAppSpecOptions(flags *pflag.FlagSet, spec *argoappv1.ApplicationSpec, ap data, err = config.ReadRemoteFile(appOpts.values) } errors.CheckError(err) - setHelmOpt(&spec.Source, helmOpts{values: string(data)}) + setHelmOpt(source, helmOpts{values: string(data)}) case "release-name": - setHelmOpt(&spec.Source, helmOpts{releaseName: appOpts.releaseName}) + setHelmOpt(source, helmOpts{releaseName: appOpts.releaseName}) case "helm-version": - setHelmOpt(&spec.Source, helmOpts{version: appOpts.helmVersion}) + setHelmOpt(source, helmOpts{version: appOpts.helmVersion}) case "helm-pass-credentials": - setHelmOpt(&spec.Source, helmOpts{passCredentials: appOpts.helmPassCredentials}) + setHelmOpt(source, helmOpts{passCredentials: appOpts.helmPassCredentials}) case "helm-set": - setHelmOpt(&spec.Source, helmOpts{helmSets: appOpts.helmSets}) + setHelmOpt(source, helmOpts{helmSets: appOpts.helmSets}) case "helm-set-string": - setHelmOpt(&spec.Source, helmOpts{helmSetStrings: appOpts.helmSetStrings}) + setHelmOpt(source, helmOpts{helmSetStrings: appOpts.helmSetStrings}) case "helm-set-file": - setHelmOpt(&spec.Source, helmOpts{helmSetFiles: appOpts.helmSetFiles}) + setHelmOpt(source, helmOpts{helmSetFiles: appOpts.helmSetFiles}) case "helm-skip-crds": - setHelmOpt(&spec.Source, helmOpts{skipCrds: appOpts.helmSkipCrds}) + setHelmOpt(source, helmOpts{skipCrds: appOpts.helmSkipCrds}) case "directory-recurse": - if spec.Source.Directory != nil { - spec.Source.Directory.Recurse = appOpts.directoryRecurse + if source.Directory != nil { + source.Directory.Recurse = appOpts.directoryRecurse } else { - spec.Source.Directory = &argoappv1.ApplicationSourceDirectory{Recurse: appOpts.directoryRecurse} + source.Directory = &argoappv1.ApplicationSourceDirectory{Recurse: appOpts.directoryRecurse} } case "directory-exclude": - if spec.Source.Directory != nil { - spec.Source.Directory.Exclude = appOpts.directoryExclude + if source.Directory != nil { + source.Directory.Exclude = appOpts.directoryExclude } else { - spec.Source.Directory = &argoappv1.ApplicationSourceDirectory{Exclude: appOpts.directoryExclude} + source.Directory = &argoappv1.ApplicationSourceDirectory{Exclude: appOpts.directoryExclude} } case "directory-include": - if spec.Source.Directory != nil { - spec.Source.Directory.Include = appOpts.directoryInclude + if source.Directory != nil { + source.Directory.Include = appOpts.directoryInclude } else { - spec.Source.Directory = &argoappv1.ApplicationSourceDirectory{Include: appOpts.directoryInclude} + source.Directory = &argoappv1.ApplicationSourceDirectory{Include: appOpts.directoryInclude} } case "config-management-plugin": - spec.Source.Plugin = &argoappv1.ApplicationSourcePlugin{Name: appOpts.configManagementPlugin} + source.Plugin = &argoappv1.ApplicationSourcePlugin{Name: appOpts.configManagementPlugin} case "dest-name": spec.Destination.Name = appOpts.destName case "dest-server": @@ -209,37 +213,37 @@ func SetAppSpecOptions(flags *pflag.FlagSet, spec *argoappv1.ApplicationSpec, ap case "project": spec.Project = appOpts.project case "nameprefix": - setKustomizeOpt(&spec.Source, kustomizeOpts{namePrefix: appOpts.namePrefix}) + setKustomizeOpt(source, kustomizeOpts{namePrefix: appOpts.namePrefix}) case "namesuffix": - setKustomizeOpt(&spec.Source, kustomizeOpts{nameSuffix: appOpts.nameSuffix}) + setKustomizeOpt(source, kustomizeOpts{nameSuffix: appOpts.nameSuffix}) case "kustomize-image": - setKustomizeOpt(&spec.Source, kustomizeOpts{images: appOpts.kustomizeImages}) + setKustomizeOpt(source, kustomizeOpts{images: appOpts.kustomizeImages}) case "kustomize-version": - setKustomizeOpt(&spec.Source, kustomizeOpts{version: appOpts.kustomizeVersion}) + setKustomizeOpt(source, kustomizeOpts{version: appOpts.kustomizeVersion}) case "kustomize-common-label": parsedLabels, err := label.Parse(appOpts.kustomizeCommonLabels) errors.CheckError(err) - setKustomizeOpt(&spec.Source, kustomizeOpts{commonLabels: parsedLabels}) + setKustomizeOpt(source, kustomizeOpts{commonLabels: parsedLabels}) case "kustomize-common-annotation": parsedAnnotations, err := label.Parse(appOpts.kustomizeCommonAnnotations) errors.CheckError(err) - setKustomizeOpt(&spec.Source, kustomizeOpts{commonAnnotations: parsedAnnotations}) + setKustomizeOpt(source, kustomizeOpts{commonAnnotations: parsedAnnotations}) case "kustomize-force-common-label": - setKustomizeOpt(&spec.Source, kustomizeOpts{forceCommonLabels: appOpts.kustomizeForceCommonLabels}) + setKustomizeOpt(source, kustomizeOpts{forceCommonLabels: appOpts.kustomizeForceCommonLabels}) case "kustomize-force-common-annotation": - setKustomizeOpt(&spec.Source, kustomizeOpts{forceCommonAnnotations: appOpts.kustomizeForceCommonAnnotations}) + setKustomizeOpt(source, kustomizeOpts{forceCommonAnnotations: appOpts.kustomizeForceCommonAnnotations}) case "jsonnet-tla-str": - setJsonnetOpt(&spec.Source, appOpts.jsonnetTlaStr, false) + setJsonnetOpt(source, appOpts.jsonnetTlaStr, false) case "jsonnet-tla-code": - setJsonnetOpt(&spec.Source, appOpts.jsonnetTlaCode, true) + setJsonnetOpt(source, appOpts.jsonnetTlaCode, true) case "jsonnet-ext-var-str": - setJsonnetOptExtVar(&spec.Source, appOpts.jsonnetExtVarStr, false) + setJsonnetOptExtVar(source, appOpts.jsonnetExtVarStr, false) case "jsonnet-ext-var-code": - setJsonnetOptExtVar(&spec.Source, appOpts.jsonnetExtVarCode, true) + setJsonnetOptExtVar(source, appOpts.jsonnetExtVarCode, true) case "jsonnet-libs": - setJsonnetOptLibs(&spec.Source, appOpts.jsonnetLibs) + setJsonnetOptLibs(source, appOpts.jsonnetLibs) case "plugin-env": - setPluginOptEnvs(&spec.Source, appOpts.pluginEnvs) + setPluginOptEnvs(source, appOpts.pluginEnvs) case "sync-policy": switch appOpts.syncPolicy { case "none": @@ -296,6 +300,7 @@ func SetAppSpecOptions(flags *pflag.FlagSet, spec *argoappv1.ApplicationSpec, ap log.Fatalf("Invalid sync-retry-limit [%d]", appOpts.retryLimit) } } + spec.Source = source }) if flags.Changed("auto-prune") { if spec.SyncPolicy == nil || spec.SyncPolicy.Automated == nil { @@ -473,8 +478,9 @@ func SetParameterOverrides(app *argoappv1.Application, parameters []string) { if len(parameters) == 0 { return } + source := app.Spec.GetSource() var sourceType argoappv1.ApplicationSourceType - if st, _ := app.Spec.Source.ExplicitType(); st != nil { + if st, _ := source.ExplicitType(); st != nil { sourceType = *st } else if app.Status.SourceType != "" { sourceType = app.Status.SourceType @@ -486,8 +492,8 @@ func SetParameterOverrides(app *argoappv1.Application, parameters []string) { switch sourceType { case argoappv1.ApplicationSourceTypeHelm: - if app.Spec.Source.Helm == nil { - app.Spec.Source.Helm = &argoappv1.ApplicationSourceHelm{} + if source.Helm == nil { + source.Helm = &argoappv1.ApplicationSourceHelm{} } for _, p := range parameters { newParam, err := argoappv1.NewHelmParameter(p, false) @@ -495,7 +501,7 @@ func SetParameterOverrides(app *argoappv1.Application, parameters []string) { log.Error(err) continue } - app.Spec.Source.Helm.AddParameter(*newParam) + source.Helm.AddParameter(*newParam) } default: log.Fatalf("Parameters can only be set against Helm applications") @@ -580,6 +586,9 @@ func constructAppsBaseOnName(appName string, labels, annotations, args []string, Name: appName, Namespace: appNs, }, + Spec: argoappv1.ApplicationSpec{ + Source: &argoappv1.ApplicationSource{}, + }, } SetAppSpecOptions(flags, &app.Spec, &appOpts) SetParameterOverrides(app, appOpts.Parameters) diff --git a/cmd/util/app_test.go b/cmd/util/app_test.go index cc59599c51fa5..2e8ddc9e0fee7 100644 --- a/cmd/util/app_test.go +++ b/cmd/util/app_test.go @@ -149,7 +149,9 @@ func (f *appOptionsFixture) SetFlag(key, value string) error { func newAppOptionsFixture() *appOptionsFixture { fixture := &appOptionsFixture{ - spec: &v1alpha1.ApplicationSpec{}, + spec: &v1alpha1.ApplicationSpec{ + Source: &v1alpha1.ApplicationSource{}, + }, command: &cobra.Command{}, options: &AppOptions{}, } diff --git a/controller/appcontroller.go b/controller/appcontroller.go index 89353d755076b..a989c5a16d7dd 100644 --- a/controller/appcontroller.go +++ b/controller/appcontroller.go @@ -415,11 +415,11 @@ func isKnownOrphanedResourceExclusion(key kube.ResourceKey, proj *appv1.AppProje func (ctrl *ApplicationController) getResourceTree(a *appv1.Application, managedResources []*appv1.ResourceDiff) (*appv1.ApplicationTree, error) { nodes := make([]appv1.ResourceNode, 0) - proj, err := ctrl.getAppProj(a) if err != nil { return nil, err } + orphanedNodesMap := make(map[kube.ResourceKey]appv1.ResourceNode) warnOrphaned := true if proj.Spec.OrphanedResources != nil { @@ -429,7 +429,6 @@ func (ctrl *ApplicationController) getResourceTree(a *appv1.Application, managed } warnOrphaned = proj.Spec.OrphanedResources.IsWarn() } - for i := range managedResources { managedResource := managedResources[i] delete(orphanedNodesMap, kube.NewResourceKey(managedResource.Group, managedResource.Kind, managedResource.Namespace, managedResource.Name)) @@ -751,6 +750,7 @@ func (ctrl *ApplicationController) Run(ctx context.Context, statusProcessors int // needs to be the qualified name of the application, i.e. /. func (ctrl *ApplicationController) requestAppRefresh(appName string, compareWith *CompareWith, after *time.Duration) { key := ctrl.toAppKey(appName) + if compareWith != nil && after != nil { ctrl.appComparisonTypeRefreshQueue.AddAfter(fmt.Sprintf("%s/%d", key, compareWith), *after) } else { @@ -1313,7 +1313,6 @@ func (ctrl *ApplicationController) processAppRefreshQueueItem() (processNext boo } ctrl.appRefreshQueue.Done(appKey) }() - obj, exists, err := ctrl.appInformer.GetIndexer().GetByKey(appKey.(string)) if err != nil { log.Errorf("Failed to get application '%s' from informer index: %+v", appKey, err) @@ -1334,9 +1333,9 @@ func (ctrl *ApplicationController) processAppRefreshQueueItem() (processNext boo if !needRefresh { return } - app := origApp.DeepCopy() logCtx := log.WithFields(log.Fields{"application": app.QualifiedName()}) + startTime := time.Now() defer func() { reconcileDuration := time.Since(startTime) @@ -1389,15 +1388,38 @@ func (ctrl *ApplicationController) processAppRefreshQueueItem() (processNext boo localManifests = opState.Operation.Sync.Manifests } - revision := app.Spec.Source.TargetRevision - if comparisonLevel == CompareWithRecent { - revision = app.Status.Sync.Revision - } + revisions := make([]string, 0) + sources := make([]appv1.ApplicationSource, 0) + + hasMultipleSources := app.Spec.HasMultipleSources() + // If we have multiple sources, we use all the sources under `sources` field and ignore source under `source` field. + // else we use the source under the source field. + if hasMultipleSources { + for _, source := range app.Spec.Sources { + // We do not perform any filtering of duplicate sources. + // Argo CD will apply and update the resources generated from the sources automatically + // based on the order in which manifests were generated + sources = append(sources, source) + revisions = append(revisions, source.TargetRevision) + } + if comparisonLevel == CompareWithRecent { + revisions = app.Status.Sync.Revisions + } + } else { + revision := app.Spec.GetSource().TargetRevision + if comparisonLevel == CompareWithRecent { + revision = app.Status.Sync.Revision + } + revisions = append(revisions, revision) + sources = append(sources, app.Spec.GetSource()) + } now := metav1.Now() - compareResult := ctrl.appStateManager.CompareAppState(app, project, revision, app.Spec.Source, + + compareResult := ctrl.appStateManager.CompareAppState(app, project, revisions, sources, refreshType == appv1.RefreshTypeHard, - comparisonLevel == CompareWithLatestForceResolve, localManifests) + comparisonLevel == CompareWithLatestForceResolve, localManifests, hasMultipleSources) + for k, v := range compareResult.timings { logCtx = logCtx.WithField(k, v.Milliseconds()) } @@ -1438,6 +1460,7 @@ func (ctrl *ApplicationController) processAppRefreshQueueItem() (processNext boo return resourceStatusKey(app.Status.Resources[i]) < resourceStatusKey(app.Status.Resources[j]) }) app.Status.SourceType = compareResult.appSourceType + app.Status.SourceTypes = compareResult.appSourceTypes ctrl.persistAppStatus(origApp, &app.Status) return } @@ -1463,27 +1486,34 @@ func (ctrl *ApplicationController) needRefreshAppStatus(app *appv1.Application, // user requested app refresh. refreshType = requestedType reason = fmt.Sprintf("%s refresh requested", refreshType) - } else if !app.Spec.Source.Equals(app.Status.Sync.ComparedTo.Source) { - reason = "spec.source differs" - compareWith = CompareWithLatestForceResolve - } else if hardExpired || softExpired { - // The commented line below mysteriously crashes if app.Status.ReconciledAt is nil - // reason = fmt.Sprintf("comparison expired. reconciledAt: %v, expiry: %v", app.Status.ReconciledAt, statusRefreshTimeout) - //TODO: find existing Golang bug or create a new one - reconciledAtStr := "never" - if app.Status.ReconciledAt != nil { - reconciledAtStr = app.Status.ReconciledAt.String() - } - reason = fmt.Sprintf("comparison expired, requesting refresh. reconciledAt: %v, expiry: %v", reconciledAtStr, statusRefreshTimeout) - if hardExpired { - reason = fmt.Sprintf("comparison expired, requesting hard refresh. reconciledAt: %v, expiry: %v", reconciledAtStr, statusHardRefreshTimeout) - refreshType = appv1.RefreshTypeHard - } - } else if !app.Spec.Destination.Equals(app.Status.Sync.ComparedTo.Destination) { - reason = "spec.destination differs" - } else if requested, level := ctrl.isRefreshRequested(app.QualifiedName()); requested { - compareWith = level - reason = "controller refresh requested" + } else { + if app.Spec.HasMultipleSources() { + if (len(app.Spec.Sources) != len(app.Status.Sync.ComparedTo.Sources)) || !reflect.DeepEqual(app.Spec.Sources, app.Status.Sync.ComparedTo.Sources) { + reason = "atleast one of the spec.sources differs" + compareWith = CompareWithLatestForceResolve + } + } else if !app.Spec.Source.Equals(app.Status.Sync.ComparedTo.Source) { + reason = "spec.source differs" + compareWith = CompareWithLatestForceResolve + } else if hardExpired || softExpired { + // The commented line below mysteriously crashes if app.Status.ReconciledAt is nil + // reason = fmt.Sprintf("comparison expired. reconciledAt: %v, expiry: %v", app.Status.ReconciledAt, statusRefreshTimeout) + //TODO: find existing Golang bug or create a new one + reconciledAtStr := "never" + if app.Status.ReconciledAt != nil { + reconciledAtStr = app.Status.ReconciledAt.String() + } + reason = fmt.Sprintf("comparison expired, requesting refresh. reconciledAt: %v, expiry: %v", reconciledAtStr, statusRefreshTimeout) + if hardExpired { + reason = fmt.Sprintf("comparison expired, requesting hard refresh. reconciledAt: %v, expiry: %v", reconciledAtStr, statusHardRefreshTimeout) + refreshType = appv1.RefreshTypeHard + } + } else if !app.Spec.Destination.Equals(app.Status.Sync.ComparedTo.Destination) { + reason = "spec.destination differs" + } else if requested, level := ctrl.isRefreshRequested(app.QualifiedName()); requested { + compareWith = level + reason = "controller refresh requested" + } } if reason != "" { @@ -1520,7 +1550,9 @@ func (ctrl *ApplicationController) refreshAppConditions(app *appv1.Application) func (ctrl *ApplicationController) normalizeApplication(orig, app *appv1.Application) { logCtx := log.WithFields(log.Fields{"application": app.QualifiedName()}) app.Spec = *argo.NormalizeApplicationSpec(&app.Spec) + patch, modified, err := diff.CreateTwoWayMergePatch(orig, app, appv1.Application{}) + if err != nil { logCtx.Errorf("error constructing app spec patch: %v", err) } else if modified { @@ -1564,7 +1596,6 @@ func (ctrl *ApplicationController) persistAppStatus(orig *appv1.Application, new logCtx.Infof("No status changes. Skipping patch") return } - logCtx.Debugf("patch: %s", string(patch)) appClient := ctrl.applicationClientset.ArgoprojV1alpha1().Applications(orig.Namespace) _, err = appClient.Patch(context.Background(), orig.Name, types.MergePatchType, patch, metav1.PatchOptions{}) if err != nil { @@ -1580,6 +1611,7 @@ func (ctrl *ApplicationController) autoSync(app *appv1.Application, syncStatus * return nil } logCtx := log.WithFields(log.Fields{"application": app.QualifiedName()}) + if app.Operation != nil { logCtx.Infof("Skipping auto-sync: another operation is in progress") return nil @@ -1611,13 +1643,15 @@ func (ctrl *ApplicationController) autoSync(app *appv1.Application, syncStatus * } desiredCommitSHA := syncStatus.Revision - alreadyAttempted, attemptPhase := alreadyAttemptedSync(app, desiredCommitSHA) + desiredCommitSHAsMS := syncStatus.Revisions + alreadyAttempted, attemptPhase := alreadyAttemptedSync(app, desiredCommitSHA, desiredCommitSHAsMS, app.Spec.HasMultipleSources()) selfHeal := app.Spec.SyncPolicy.Automated.SelfHeal op := appv1.Operation{ Sync: &appv1.SyncOperation{ Revision: desiredCommitSHA, Prune: app.Spec.SyncPolicy.Automated.Prune, SyncOptions: app.Spec.SyncPolicy.SyncOptions, + Revisions: desiredCommitSHAsMS, }, InitiatedBy: appv1.OperationInitiator{Automated: true}, Retry: appv1.RetryStrategy{Limit: 5}, @@ -1669,7 +1703,6 @@ func (ctrl *ApplicationController) autoSync(app *appv1.Application, syncStatus * return &appv1.ApplicationCondition{Type: appv1.ApplicationConditionSyncError, Message: message} } } - appIf := ctrl.applicationClientset.ArgoprojV1alpha1().Applications(app.Namespace) _, err := argo.SetAppOperation(appIf, app.Name, &op) if err != nil { @@ -1684,20 +1717,41 @@ func (ctrl *ApplicationController) autoSync(app *appv1.Application, syncStatus * // alreadyAttemptedSync returns whether or not the most recent sync was performed against the // commitSHA and with the same app source config which are currently set in the app -func alreadyAttemptedSync(app *appv1.Application, commitSHA string) (bool, synccommon.OperationPhase) { +func alreadyAttemptedSync(app *appv1.Application, commitSHA string, commitSHAsMS []string, hasMultipleSources bool) (bool, synccommon.OperationPhase) { if app.Status.OperationState == nil || app.Status.OperationState.Operation.Sync == nil || app.Status.OperationState.SyncResult == nil { return false, "" } - if app.Status.OperationState.SyncResult.Revision != commitSHA { - return false, "" + if hasMultipleSources { + if !reflect.DeepEqual(app.Status.OperationState.SyncResult.Revisions, commitSHAsMS) { + return false, "" + } + } else { + if app.Status.OperationState.SyncResult.Revision != commitSHA { + return false, "" + } + } + + if hasMultipleSources { + // Ignore differences in target revision, since we already just verified commitSHAs are equal, + // and we do not want to trigger auto-sync due to things like HEAD != master + specSources := app.Spec.Sources.DeepCopy() + syncSources := app.Status.OperationState.SyncResult.Sources.DeepCopy() + for _, source := range specSources { + source.TargetRevision = "" + } + for _, source := range syncSources { + source.TargetRevision = "" + } + return reflect.DeepEqual(app.Spec.Sources, app.Status.OperationState.SyncResult.Sources), app.Status.OperationState.Phase + } else { + // Ignore differences in target revision, since we already just verified commitSHAs are equal, + // and we do not want to trigger auto-sync due to things like HEAD != master + specSource := app.Spec.Source.DeepCopy() + specSource.TargetRevision = "" + syncResSource := app.Status.OperationState.SyncResult.Source.DeepCopy() + syncResSource.TargetRevision = "" + return reflect.DeepEqual(app.Spec.GetSource(), app.Status.OperationState.SyncResult.Source), app.Status.OperationState.Phase } - // Ignore differences in target revision, since we already just verified commitSHAs are equal, - // and we do not want to trigger auto-sync due to things like HEAD != master - specSource := app.Spec.Source.DeepCopy() - specSource.TargetRevision = "" - syncResSource := app.Status.OperationState.SyncResult.Source.DeepCopy() - syncResSource.TargetRevision = "" - return reflect.DeepEqual(app.Spec.Source, app.Status.OperationState.SyncResult.Source), app.Status.OperationState.Phase } func (ctrl *ApplicationController) shouldSelfHeal(app *appv1.Application) (bool, time.Duration) { diff --git a/controller/appcontroller_test.go b/controller/appcontroller_test.go index 037af67ef715f..fff4c7f37db5c 100644 --- a/controller/appcontroller_test.go +++ b/controller/appcontroller_test.go @@ -865,7 +865,7 @@ func TestNeedRefreshAppStatus(t *testing.T) { app.Status.Sync = argoappv1.SyncStatus{ Status: argoappv1.SyncStatusCodeSynced, ComparedTo: argoappv1.ComparedTo{ - Source: app.Spec.Source, + Source: app.Spec.GetSource(), Destination: app.Spec.Destination, }, } @@ -909,7 +909,7 @@ func TestNeedRefreshAppStatus(t *testing.T) { app.Status.Sync = argoappv1.SyncStatus{ Status: argoappv1.SyncStatusCodeSynced, ComparedTo: argoappv1.ComparedTo{ - Source: app.Spec.Source, + Source: app.Spec.GetSource(), Destination: app.Spec.Destination, }, } @@ -1012,7 +1012,7 @@ func TestUpdateReconciledAt(t *testing.T) { app := newFakeApp() reconciledAt := metav1.NewTime(time.Now().Add(-1 * time.Second)) app.Status = argoappv1.ApplicationStatus{ReconciledAt: &reconciledAt} - app.Status.Sync = argoappv1.SyncStatus{ComparedTo: argoappv1.ComparedTo{Source: app.Spec.Source, Destination: app.Spec.Destination}} + app.Status.Sync = argoappv1.SyncStatus{ComparedTo: argoappv1.ComparedTo{Source: app.Spec.GetSource(), Destination: app.Spec.Destination}} ctrl := newFakeController(&fakeData{ apps: []runtime.Object{app, &defaultProj}, manifestResponse: &apiclient.ManifestResponse{ diff --git a/controller/metrics/metrics.go b/controller/metrics/metrics.go index d3022aaf30687..3cd9837ff7036 100644 --- a/controller/metrics/metrics.go +++ b/controller/metrics/metrics.go @@ -381,7 +381,7 @@ func (c *appCollector) collectApps(ch chan<- prometheus.Metric, app *argoappv1.A healthStatus = health.HealthStatusUnknown } - addGauge(descAppInfo, 1, git.NormalizeGitURL(app.Spec.Source.RepoURL), app.Spec.Destination.Server, app.Spec.Destination.Namespace, string(syncStatus), string(healthStatus), operation) + addGauge(descAppInfo, 1, git.NormalizeGitURL(app.Spec.GetSource().RepoURL), app.Spec.Destination.Server, app.Spec.Destination.Namespace, string(syncStatus), string(healthStatus), operation) if len(c.appLabels) > 0 { labelValues := []string{} diff --git a/controller/state.go b/controller/state.go index 8cbc78d2b4274..b9eb784e89023 100644 --- a/controller/state.go +++ b/controller/state.go @@ -62,7 +62,7 @@ type managedResource struct { // AppStateManager defines methods which allow to compare application spec and actual application state. type AppStateManager interface { - CompareAppState(app *v1alpha1.Application, project *appv1.AppProject, revision string, source v1alpha1.ApplicationSource, noCache bool, noRevisionCache bool, localObjects []string) *comparisonResult + CompareAppState(app *v1alpha1.Application, project *appv1.AppProject, revisions []string, sources []v1alpha1.ApplicationSource, noCache bool, noRevisionCache bool, localObjects []string, hasMultipleSources bool) *comparisonResult SyncAppState(app *v1alpha1.Application, state *v1alpha1.OperationState) } @@ -75,6 +75,8 @@ type comparisonResult struct { reconciliationResult sync.ReconciliationResult diffConfig argodiff.DiffConfig appSourceType v1alpha1.ApplicationSourceType + // appSourceTypes stores the SourceType for each application source under sources field + appSourceTypes []v1alpha1.ApplicationSourceType // timings maps phases of comparison to the duration it took to complete (for statistical purposes) timings map[string]time.Duration diffResultList *diff.DiffResultList @@ -105,7 +107,8 @@ type appStateManager struct { persistResourceHealth bool } -func (m *appStateManager) getRepoObjs(app *v1alpha1.Application, source v1alpha1.ApplicationSource, appLabelKey, revision string, noCache, noRevisionCache, verifySignature bool, proj *v1alpha1.AppProject) ([]*unstructured.Unstructured, *apiclient.ManifestResponse, error) { +func (m *appStateManager) getRepoObjs(app *v1alpha1.Application, sources []v1alpha1.ApplicationSource, appLabelKey string, revisions []string, noCache, noRevisionCache, verifySignature bool, proj *v1alpha1.AppProject) ([]*unstructured.Unstructured, map[*v1alpha1.ApplicationSource]*apiclient.ManifestResponse, error) { + ts := stats.NewTimingStats() helmRepos, err := m.db.ListHelmRepositories(context.Background()) if err != nil { @@ -115,11 +118,7 @@ func (m *appStateManager) getRepoObjs(app *v1alpha1.Application, source v1alpha1 if err != nil { return nil, nil, err } - ts.AddCheckpoint("helm_ms") - repo, err := m.db.GetRepository(context.Background(), source.RepoURL) - if err != nil { - return nil, nil, err - } + ts.AddCheckpoint("repo_ms") helmRepositoryCredentials, err := m.db.GetAllHelmRepositoryCredentials(context.Background()) if err != nil { @@ -129,15 +128,6 @@ func (m *appStateManager) getRepoObjs(app *v1alpha1.Application, source v1alpha1 if err != nil { return nil, nil, err } - conn, repoClient, err := m.repoClientset.NewRepoServerClient() - if err != nil { - return nil, nil, err - } - defer io.Close(conn) - - if revision == "" { - revision = source.TargetRevision - } plugins, err := m.settingsMgr.GetConfigManagementPlugins() if err != nil { @@ -158,48 +148,87 @@ func (m *appStateManager) getRepoObjs(app *v1alpha1.Application, source v1alpha1 return nil, nil, err } - kustomizeOptions, err := kustomizeSettings.GetOptions(app.Spec.Source) - if err != nil { - return nil, nil, err - } - helmOptions, err := m.settingsMgr.GetHelmSettings() if err != nil { return nil, nil, err } + ts.AddCheckpoint("build_options_ms") serverVersion, apiResources, err := m.liveStateCache.GetVersionsInfo(app.Spec.Destination.Server) if err != nil { return nil, nil, err } - ts.AddCheckpoint("version_ms") - manifestInfo, err := repoClient.GenerateManifest(context.Background(), &apiclient.ManifestRequest{ - Repo: repo, - Repos: permittedHelmRepos, - Revision: revision, - NoCache: noCache, - NoRevisionCache: noRevisionCache, - AppLabelKey: appLabelKey, - AppName: app.InstanceName(m.namespace), - Namespace: app.Spec.Destination.Namespace, - ApplicationSource: &source, - Plugins: tools, - KustomizeOptions: kustomizeOptions, - KubeVersion: serverVersion, - ApiVersions: argo.APIResourcesToStrings(apiResources, true), - VerifySignature: verifySignature, - HelmRepoCreds: permittedHelmCredentials, - TrackingMethod: string(argo.GetTrackingMethod(m.settingsMgr)), - EnabledSourceTypes: enabledSourceTypes, - HelmOptions: helmOptions, - }) + conn, repoClient, err := m.repoClientset.NewRepoServerClient() if err != nil { return nil, nil, err } - targetObjs, err := unmarshalManifests(manifestInfo.Manifests) + defer io.Close(conn) + + manifestInfoMap := make(map[*v1alpha1.ApplicationSource]*apiclient.ManifestResponse) + targetObjs := make([]*unstructured.Unstructured, 0) + // Store the map of all sources having ref field into a map for applications with sources field + refSources, err := argo.GetRefSources(context.Background(), app.Spec, m.db) if err != nil { - return nil, nil, err + return nil, nil, fmt.Errorf("failed to get ref sources: %v", err) + } + + for i, source := range sources { + if len(revisions) < len(sources) || revisions[i] == "" { + revisions[i] = source.TargetRevision + } + ts.AddCheckpoint("helm_ms") + repo, err := m.db.GetRepository(context.Background(), source.RepoURL) + if err != nil { + return nil, nil, err + } + kustomizeOptions, err := kustomizeSettings.GetOptions(source) + if err != nil { + return nil, nil, err + } + + ts.AddCheckpoint("version_ms") + log.Debugf("Generating Manifest for source %s revision %s", source, revisions[i]) + manifestInfo, err := repoClient.GenerateManifest(context.Background(), &apiclient.ManifestRequest{ + Repo: repo, + Repos: permittedHelmRepos, + Revision: revisions[i], + NoCache: noCache, + NoRevisionCache: noRevisionCache, + AppLabelKey: appLabelKey, + AppName: app.InstanceName(m.namespace), + Namespace: app.Spec.Destination.Namespace, + ApplicationSource: &source, + Plugins: tools, + KustomizeOptions: kustomizeOptions, + KubeVersion: serverVersion, + ApiVersions: argo.APIResourcesToStrings(apiResources, true), + VerifySignature: verifySignature, + HelmRepoCreds: permittedHelmCredentials, + TrackingMethod: string(argo.GetTrackingMethod(m.settingsMgr)), + EnabledSourceTypes: enabledSourceTypes, + HelmOptions: helmOptions, + HasMultipleSources: app.Spec.HasMultipleSources(), + RefSources: refSources, + }) + if err != nil { + return nil, nil, err + } + + // GenerateManifest can return empty ManifestResponse without error if app has multiple sources + // and if any of the source does not have path and chart field not specified. + // In that scenario, we continue to the next source + if app.Spec.HasMultipleSources() && len(manifestInfo.Manifests) == 0 { + continue + } + + targetObj, err := unmarshalManifests(manifestInfo.Manifests) + + if err != nil { + return nil, nil, err + } + targetObjs = append(targetObjs, targetObj...) + manifestInfoMap[&source] = manifestInfo } ts.AddCheckpoint("unmarshal_ms") @@ -209,7 +238,7 @@ func (m *appStateManager) getRepoObjs(app *v1alpha1.Application, source v1alpha1 } logCtx = logCtx.WithField("time_ms", time.Since(ts.StartTime).Milliseconds()) logCtx.Info("getRepoObjs stats") - return targetObjs, manifestInfo, nil + return targetObjs, manifestInfoMap, nil } func unmarshalManifests(manifests []string) ([]*unstructured.Unstructured, error) { @@ -325,7 +354,7 @@ func verifyGnuPGSignature(revision string, project *appv1.AppProject, manifestIn // CompareAppState compares application git state to the live app state, using the specified // revision and supplied source. If revision or overrides are empty, then compares against // revision and overrides in the app spec. -func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *appv1.AppProject, revision string, source v1alpha1.ApplicationSource, noCache bool, noRevisionCache bool, localManifests []string) *comparisonResult { +func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *appv1.AppProject, revisions []string, sources []v1alpha1.ApplicationSource, noCache bool, noRevisionCache bool, localManifests []string, hasMultipleSources bool) *comparisonResult { ts := stats.NewTimingStats() appLabelKey, resourceOverrides, resFilter, err := m.getComparisonSettings() @@ -333,12 +362,24 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *ap // return unknown comparison result if basic comparison settings cannot be loaded if err != nil { - return &comparisonResult{ - syncStatus: &v1alpha1.SyncStatus{ - ComparedTo: appv1.ComparedTo{Source: source, Destination: app.Spec.Destination}, - Status: appv1.SyncStatusCodeUnknown, - }, - healthStatus: &appv1.HealthStatus{Status: health.HealthStatusUnknown}, + if hasMultipleSources { + return &comparisonResult{ + syncStatus: &v1alpha1.SyncStatus{ + ComparedTo: appv1.ComparedTo{Destination: app.Spec.Destination, Sources: sources}, + Status: appv1.SyncStatusCodeUnknown, + Revisions: revisions, + }, + healthStatus: &appv1.HealthStatus{Status: health.HealthStatusUnknown}, + } + } else { + return &comparisonResult{ + syncStatus: &v1alpha1.SyncStatus{ + ComparedTo: appv1.ComparedTo{Source: sources[0], Destination: app.Spec.Destination}, + Status: appv1.SyncStatusCodeUnknown, + Revision: revisions[0], + }, + healthStatus: &appv1.HealthStatus{Status: health.HealthStatusUnknown}, + } } } @@ -356,11 +397,21 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *ap logCtx.Infof("Comparing app state (cluster: %s, namespace: %s)", app.Spec.Destination.Server, app.Spec.Destination.Namespace) var targetObjs []*unstructured.Unstructured - var manifestInfo *apiclient.ManifestResponse now := metav1.Now() + var manifestInfoMap map[*v1alpha1.ApplicationSource]*apiclient.ManifestResponse + if len(localManifests) == 0 { - targetObjs, manifestInfo, err = m.getRepoObjs(app, source, appLabelKey, revision, noCache, noRevisionCache, verifySignature, project) + // If the length of revisions is not same as the length of sources, + // we take the revisions from the sources directly for all the sources. + if len(revisions) != len(sources) { + revisions = make([]string, 0) + for _, source := range sources { + revisions = append(revisions, source.TargetRevision) + } + } + + targetObjs, manifestInfoMap, err = m.getRepoObjs(app, sources, appLabelKey, revisions, noCache, noRevisionCache, verifySignature, project) if err != nil { targetObjs = make([]*unstructured.Unstructured, 0) conditions = append(conditions, v1alpha1.ApplicationCondition{Type: v1alpha1.ApplicationConditionComparisonError, Message: err.Error(), LastTransitionTime: &now}) @@ -382,7 +433,10 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *ap failedToLoadObjs = true } } - manifestInfo = nil + // empty out manifestInfoMap + for as := range manifestInfoMap { + delete(manifestInfoMap, as) + } } ts.AddCheckpoint("git_ms") @@ -416,6 +470,7 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *ap conditions = append(conditions, v1alpha1.ApplicationCondition{Type: v1alpha1.ApplicationConditionComparisonError, Message: err.Error(), LastTransitionTime: &now}) failedToLoadObjs = true } + logCtx.Debugf("Retrieved lived manifests") // filter out all resources which are not permitted in the application project @@ -459,10 +514,16 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *ap log.Warnf("Could not get compare options from ConfigMap (assuming defaults): %v", err) compareOptions = settings.GetDefaultDiffOptions() } + manifestRevisions := make([]string, 0) + + for _, manifestInfo := range manifestInfoMap { + manifestRevisions = append(manifestRevisions, manifestInfo.Revision) + } // restore comparison using cached diff result if previous comparison was performed for the same revision - revisionChanged := manifestInfo == nil || app.Status.Sync.Revision != manifestInfo.Revision - specChanged := !reflect.DeepEqual(app.Status.Sync.ComparedTo, appv1.ComparedTo{Source: app.Spec.Source, Destination: app.Spec.Destination}) + revisionChanged := len(manifestInfoMap) != len(sources) || !reflect.DeepEqual(app.Status.Sync.Revisions, manifestRevisions) + specChanged := !reflect.DeepEqual(app.Status.Sync.ComparedTo, appv1.ComparedTo{Source: app.Spec.GetSource(), Destination: app.Spec.Destination, Sources: sources}) + _, refreshRequested := app.IsRefreshRequested() noCache = noCache || refreshRequested || app.Status.Expired(m.statusRefreshTimeout) || specChanged || revisionChanged @@ -591,16 +652,32 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *ap if failedToLoadObjs { syncCode = v1alpha1.SyncStatusCodeUnknown } - syncStatus := v1alpha1.SyncStatus{ - ComparedTo: appv1.ComparedTo{ - Source: source, - Destination: app.Spec.Destination, - }, - Status: syncCode, + var revision string + + if !hasMultipleSources && len(manifestRevisions) > 0 { + revision = manifestRevisions[0] } - if manifestInfo != nil { - syncStatus.Revision = manifestInfo.Revision + var syncStatus v1alpha1.SyncStatus + if hasMultipleSources { + syncStatus = v1alpha1.SyncStatus{ + ComparedTo: appv1.ComparedTo{ + Destination: app.Spec.Destination, + Sources: sources, + }, + Status: syncCode, + Revisions: manifestRevisions, + } + } else { + syncStatus = v1alpha1.SyncStatus{ + ComparedTo: appv1.ComparedTo{ + Destination: app.Spec.Destination, + Source: app.Spec.GetSource(), + }, + Status: syncCode, + Revision: revision, + } } + ts.AddCheckpoint("sync_ms") healthStatus, err := setApplicationHealth(managedResources, resourceSummaries, resourceOverrides, app, m.persistResourceHealth) @@ -611,8 +688,10 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *ap // Git has already performed the signature verification via its GPG interface, and the result is available // in the manifest info received from the repository server. We now need to form our opinion about the result // and stop processing if we do not agree about the outcome. - if gpg.IsGPGEnabled() && verifySignature && manifestInfo != nil { - conditions = append(conditions, verifyGnuPGSignature(revision, project, manifestInfo)...) + for _, manifestInfo := range manifestInfoMap { + if gpg.IsGPGEnabled() && verifySignature && manifestInfo != nil { + conditions = append(conditions, verifyGnuPGSignature(manifestInfo.Revision, project, manifestInfo)...) + } } compRes := comparisonResult{ @@ -624,9 +703,18 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *ap diffConfig: diffConfig, diffResultList: diffResults, } - if manifestInfo != nil { - compRes.appSourceType = v1alpha1.ApplicationSourceType(manifestInfo.SourceType) + + if hasMultipleSources { + for _, manifestInfo := range manifestInfoMap { + compRes.appSourceTypes = append(compRes.appSourceTypes, appv1.ApplicationSourceType(manifestInfo.SourceType)) + } + } else { + for _, manifestInfo := range manifestInfoMap { + compRes.appSourceType = v1alpha1.ApplicationSourceType(manifestInfo.SourceType) + break + } } + app.Status.SetConditions(conditions, map[appv1.ApplicationConditionType]bool{ appv1.ApplicationConditionComparisonError: true, appv1.ApplicationConditionSharedResourceWarning: true, @@ -638,18 +726,29 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *ap return &compRes } -func (m *appStateManager) persistRevisionHistory(app *v1alpha1.Application, revision string, source v1alpha1.ApplicationSource, startedAt metav1.Time) error { +func (m *appStateManager) persistRevisionHistory(app *v1alpha1.Application, revision string, source v1alpha1.ApplicationSource, revisions []string, sources []v1alpha1.ApplicationSource, hasMultipleSources bool, startedAt metav1.Time) error { var nextID int64 if len(app.Status.History) > 0 { nextID = app.Status.History.LastRevisionHistory().ID + 1 } - app.Status.History = append(app.Status.History, v1alpha1.RevisionHistory{ - Revision: revision, - DeployedAt: metav1.NewTime(time.Now().UTC()), - DeployStartedAt: &startedAt, - ID: nextID, - Source: source, - }) + + if hasMultipleSources { + app.Status.History = append(app.Status.History, v1alpha1.RevisionHistory{ + DeployedAt: metav1.NewTime(time.Now().UTC()), + DeployStartedAt: &startedAt, + ID: nextID, + Sources: sources, + Revisions: revisions, + }) + } else { + app.Status.History = append(app.Status.History, v1alpha1.RevisionHistory{ + Revision: revision, + DeployedAt: metav1.NewTime(time.Now().UTC()), + DeployStartedAt: &startedAt, + ID: nextID, + Source: source, + }) + } app.Status.History = app.Status.History.Trunc(app.Spec.GetRevisionHistoryLimit()) diff --git a/controller/state_test.go b/controller/state_test.go index 7d577ea1cb82d..8883464267538 100644 --- a/controller/state_test.go +++ b/controller/state_test.go @@ -38,7 +38,11 @@ func TestCompareAppStateEmpty(t *testing.T) { managedLiveObjs: make(map[kube.ResourceKey]*unstructured.Unstructured), } ctrl := newFakeController(&data) - compRes := ctrl.appStateManager.CompareAppState(app, &defaultProj, "", app.Spec.Source, false, false, nil) + sources := make([]argoappv1.ApplicationSource, 0) + sources = append(sources, app.Spec.GetSource()) + revisions := make([]string, 0) + revisions = append(revisions, "") + compRes := ctrl.appStateManager.CompareAppState(app, &defaultProj, revisions, sources, false, false, nil, false) assert.NotNil(t, compRes) assert.NotNil(t, compRes.syncStatus) assert.Equal(t, argoappv1.SyncStatusCodeSynced, compRes.syncStatus.Status) @@ -61,7 +65,11 @@ func TestCompareAppStateMissing(t *testing.T) { managedLiveObjs: make(map[kube.ResourceKey]*unstructured.Unstructured), } ctrl := newFakeController(&data) - compRes := ctrl.appStateManager.CompareAppState(app, &defaultProj, "", app.Spec.Source, false, false, nil) + sources := make([]argoappv1.ApplicationSource, 0) + sources = append(sources, app.Spec.GetSource()) + revisions := make([]string, 0) + revisions = append(revisions, "") + compRes := ctrl.appStateManager.CompareAppState(app, &defaultProj, revisions, sources, false, false, nil, false) assert.NotNil(t, compRes) assert.NotNil(t, compRes.syncStatus) assert.Equal(t, argoappv1.SyncStatusCodeOutOfSync, compRes.syncStatus.Status) @@ -88,7 +96,11 @@ func TestCompareAppStateExtra(t *testing.T) { }, } ctrl := newFakeController(&data) - compRes := ctrl.appStateManager.CompareAppState(app, &defaultProj, "", app.Spec.Source, false, false, nil) + sources := make([]argoappv1.ApplicationSource, 0) + sources = append(sources, app.Spec.GetSource()) + revisions := make([]string, 0) + revisions = append(revisions, "") + compRes := ctrl.appStateManager.CompareAppState(app, &defaultProj, revisions, sources, false, false, nil, false) assert.NotNil(t, compRes) assert.Equal(t, argoappv1.SyncStatusCodeOutOfSync, compRes.syncStatus.Status) assert.Equal(t, 1, len(compRes.resources)) @@ -114,7 +126,11 @@ func TestCompareAppStateHook(t *testing.T) { managedLiveObjs: make(map[kube.ResourceKey]*unstructured.Unstructured), } ctrl := newFakeController(&data) - compRes := ctrl.appStateManager.CompareAppState(app, &defaultProj, "", app.Spec.Source, false, false, nil) + sources := make([]argoappv1.ApplicationSource, 0) + sources = append(sources, app.Spec.GetSource()) + revisions := make([]string, 0) + revisions = append(revisions, "") + compRes := ctrl.appStateManager.CompareAppState(app, &defaultProj, revisions, sources, false, false, nil, false) assert.NotNil(t, compRes) assert.Equal(t, argoappv1.SyncStatusCodeSynced, compRes.syncStatus.Status) assert.Equal(t, 0, len(compRes.resources)) @@ -141,7 +157,11 @@ func TestCompareAppStateSkipHook(t *testing.T) { managedLiveObjs: make(map[kube.ResourceKey]*unstructured.Unstructured), } ctrl := newFakeController(&data) - compRes := ctrl.appStateManager.CompareAppState(app, &defaultProj, "", app.Spec.Source, false, false, nil) + sources := make([]argoappv1.ApplicationSource, 0) + sources = append(sources, app.Spec.GetSource()) + revisions := make([]string, 0) + revisions = append(revisions, "") + compRes := ctrl.appStateManager.CompareAppState(app, &defaultProj, revisions, sources, false, false, nil, false) assert.NotNil(t, compRes) assert.Equal(t, argoappv1.SyncStatusCodeSynced, compRes.syncStatus.Status) assert.Equal(t, 1, len(compRes.resources)) @@ -167,7 +187,11 @@ func TestCompareAppStateCompareOptionIgnoreExtraneous(t *testing.T) { } ctrl := newFakeController(&data) - compRes := ctrl.appStateManager.CompareAppState(app, &defaultProj, "", app.Spec.Source, false, false, nil) + sources := make([]argoappv1.ApplicationSource, 0) + sources = append(sources, app.Spec.GetSource()) + revisions := make([]string, 0) + revisions = append(revisions, "") + compRes := ctrl.appStateManager.CompareAppState(app, &defaultProj, revisions, sources, false, false, nil, false) assert.NotNil(t, compRes) assert.Equal(t, argoappv1.SyncStatusCodeSynced, compRes.syncStatus.Status) @@ -195,7 +219,11 @@ func TestCompareAppStateExtraHook(t *testing.T) { }, } ctrl := newFakeController(&data) - compRes := ctrl.appStateManager.CompareAppState(app, &defaultProj, "", app.Spec.Source, false, false, nil) + sources := make([]argoappv1.ApplicationSource, 0) + sources = append(sources, app.Spec.GetSource()) + revisions := make([]string, 0) + revisions = append(revisions, "") + compRes := ctrl.appStateManager.CompareAppState(app, &defaultProj, revisions, sources, false, false, nil, false) assert.NotNil(t, compRes) assert.Equal(t, argoappv1.SyncStatusCodeSynced, compRes.syncStatus.Status) @@ -238,7 +266,11 @@ func TestCompareAppStateDuplicatedNamespacedResources(t *testing.T) { }, } ctrl := newFakeController(&data) - compRes := ctrl.appStateManager.CompareAppState(app, &defaultProj, "", app.Spec.Source, false, false, nil) + sources := make([]argoappv1.ApplicationSource, 0) + sources = append(sources, app.Spec.GetSource()) + revisions := make([]string, 0) + revisions = append(revisions, "") + compRes := ctrl.appStateManager.CompareAppState(app, &defaultProj, revisions, sources, false, false, nil, false) assert.NotNil(t, compRes) assert.Equal(t, 1, len(app.Status.Conditions)) @@ -289,7 +321,11 @@ func TestSetHealth(t *testing.T) { }, }) - compRes := ctrl.appStateManager.CompareAppState(app, &defaultProj, "", app.Spec.Source, false, false, nil) + sources := make([]argoappv1.ApplicationSource, 0) + sources = append(sources, app.Spec.GetSource()) + revisions := make([]string, 0) + revisions = append(revisions, "") + compRes := ctrl.appStateManager.CompareAppState(app, &defaultProj, revisions, sources, false, false, nil, false) assert.Equal(t, health.HealthStatusHealthy, compRes.healthStatus.Status) } @@ -321,7 +357,11 @@ func TestSetHealthSelfReferencedApp(t *testing.T) { }, }) - compRes := ctrl.appStateManager.CompareAppState(app, &defaultProj, "", app.Spec.Source, false, false, nil) + sources := make([]argoappv1.ApplicationSource, 0) + sources = append(sources, app.Spec.GetSource()) + revisions := make([]string, 0) + revisions = append(revisions, "") + compRes := ctrl.appStateManager.CompareAppState(app, &defaultProj, revisions, sources, false, false, nil, false) assert.Equal(t, health.HealthStatusHealthy, compRes.healthStatus.Status) } @@ -391,7 +431,11 @@ func TestReturnUnknownComparisonStateOnSettingLoadError(t *testing.T) { }, }) - compRes := ctrl.appStateManager.CompareAppState(app, &defaultProj, "", app.Spec.Source, false, false, nil) + sources := make([]argoappv1.ApplicationSource, 0) + sources = append(sources, app.Spec.GetSource()) + revisions := make([]string, 0) + revisions = append(revisions, "") + compRes := ctrl.appStateManager.CompareAppState(app, &defaultProj, revisions, sources, false, false, nil, false) assert.Equal(t, health.HealthStatusUnknown, compRes.healthStatus.Status) assert.Equal(t, argoappv1.SyncStatusCodeUnknown, compRes.syncStatus.Status) @@ -438,7 +482,7 @@ func Test_appStateManager_persistRevisionHistory(t *testing.T) { app.Spec.RevisionHistoryLimit = &i } addHistory := func() { - err := manager.persistRevisionHistory(app, "my-revision", argoappv1.ApplicationSource{}, metav1.Time{}) + err := manager.persistRevisionHistory(app, "my-revision", argoappv1.ApplicationSource{}, []string{}, []argoappv1.ApplicationSource{}, false, metav1.Time{}) assert.NoError(t, err) } addHistory() @@ -474,7 +518,7 @@ func Test_appStateManager_persistRevisionHistory(t *testing.T) { assert.Len(t, app.Status.History, 9) metav1NowTime := metav1.NewTime(time.Now()) - err := manager.persistRevisionHistory(app, "my-revision", argoappv1.ApplicationSource{}, metav1NowTime) + err := manager.persistRevisionHistory(app, "my-revision", argoappv1.ApplicationSource{}, []string{}, []argoappv1.ApplicationSource{}, false, metav1NowTime) assert.NoError(t, err) assert.Equal(t, app.Status.History.LastRevisionHistory().DeployStartedAt, &metav1NowTime) } @@ -528,7 +572,11 @@ func TestSignedResponseNoSignatureRequired(t *testing.T) { managedLiveObjs: make(map[kube.ResourceKey]*unstructured.Unstructured), } ctrl := newFakeController(&data) - compRes := ctrl.appStateManager.CompareAppState(app, &defaultProj, "", app.Spec.Source, false, false, nil) + sources := make([]argoappv1.ApplicationSource, 0) + sources = append(sources, app.Spec.GetSource()) + revisions := make([]string, 0) + revisions = append(revisions, "") + compRes := ctrl.appStateManager.CompareAppState(app, &defaultProj, revisions, sources, false, false, nil, false) assert.NotNil(t, compRes) assert.NotNil(t, compRes.syncStatus) assert.Equal(t, argoappv1.SyncStatusCodeSynced, compRes.syncStatus.Status) @@ -550,7 +598,11 @@ func TestSignedResponseNoSignatureRequired(t *testing.T) { managedLiveObjs: make(map[kube.ResourceKey]*unstructured.Unstructured), } ctrl := newFakeController(&data) - compRes := ctrl.appStateManager.CompareAppState(app, &defaultProj, "", app.Spec.Source, false, false, nil) + sources := make([]argoappv1.ApplicationSource, 0) + sources = append(sources, app.Spec.GetSource()) + revisions := make([]string, 0) + revisions = append(revisions, "") + compRes := ctrl.appStateManager.CompareAppState(app, &defaultProj, revisions, sources, false, false, nil, false) assert.NotNil(t, compRes) assert.NotNil(t, compRes.syncStatus) assert.Equal(t, argoappv1.SyncStatusCodeSynced, compRes.syncStatus.Status) @@ -579,7 +631,11 @@ func TestSignedResponseSignatureRequired(t *testing.T) { managedLiveObjs: make(map[kube.ResourceKey]*unstructured.Unstructured), } ctrl := newFakeController(&data) - compRes := ctrl.appStateManager.CompareAppState(app, &signedProj, "", app.Spec.Source, false, false, nil) + sources := make([]argoappv1.ApplicationSource, 0) + sources = append(sources, app.Spec.GetSource()) + revisions := make([]string, 0) + revisions = append(revisions, "") + compRes := ctrl.appStateManager.CompareAppState(app, &signedProj, revisions, sources, false, false, nil, false) assert.NotNil(t, compRes) assert.NotNil(t, compRes.syncStatus) assert.Equal(t, argoappv1.SyncStatusCodeSynced, compRes.syncStatus.Status) @@ -601,7 +657,11 @@ func TestSignedResponseSignatureRequired(t *testing.T) { managedLiveObjs: make(map[kube.ResourceKey]*unstructured.Unstructured), } ctrl := newFakeController(&data) - compRes := ctrl.appStateManager.CompareAppState(app, &signedProj, "abc123", app.Spec.Source, false, false, nil) + sources := make([]argoappv1.ApplicationSource, 0) + sources = append(sources, app.Spec.GetSource()) + revisions := make([]string, 0) + revisions = append(revisions, "abc123") + compRes := ctrl.appStateManager.CompareAppState(app, &signedProj, revisions, sources, false, false, nil, false) assert.NotNil(t, compRes) assert.NotNil(t, compRes.syncStatus) assert.Equal(t, argoappv1.SyncStatusCodeSynced, compRes.syncStatus.Status) @@ -623,7 +683,11 @@ func TestSignedResponseSignatureRequired(t *testing.T) { managedLiveObjs: make(map[kube.ResourceKey]*unstructured.Unstructured), } ctrl := newFakeController(&data) - compRes := ctrl.appStateManager.CompareAppState(app, &signedProj, "abc123", app.Spec.Source, false, false, nil) + sources := make([]argoappv1.ApplicationSource, 0) + sources = append(sources, app.Spec.GetSource()) + revisions := make([]string, 0) + revisions = append(revisions, "abc123") + compRes := ctrl.appStateManager.CompareAppState(app, &signedProj, revisions, sources, false, false, nil, false) assert.NotNil(t, compRes) assert.NotNil(t, compRes.syncStatus) assert.Equal(t, argoappv1.SyncStatusCodeSynced, compRes.syncStatus.Status) @@ -645,7 +709,11 @@ func TestSignedResponseSignatureRequired(t *testing.T) { managedLiveObjs: make(map[kube.ResourceKey]*unstructured.Unstructured), } ctrl := newFakeController(&data) - compRes := ctrl.appStateManager.CompareAppState(app, &signedProj, "abc123", app.Spec.Source, false, false, nil) + sources := make([]argoappv1.ApplicationSource, 0) + sources = append(sources, app.Spec.GetSource()) + revisions := make([]string, 0) + revisions = append(revisions, "abc123") + compRes := ctrl.appStateManager.CompareAppState(app, &signedProj, revisions, sources, false, false, nil, false) assert.NotNil(t, compRes) assert.NotNil(t, compRes.syncStatus) assert.Equal(t, argoappv1.SyncStatusCodeSynced, compRes.syncStatus.Status) @@ -670,7 +738,11 @@ func TestSignedResponseSignatureRequired(t *testing.T) { ctrl := newFakeController(&data) testProj := signedProj testProj.Spec.SignatureKeys[0].KeyID = "4AEE18F83AFDEB24" - compRes := ctrl.appStateManager.CompareAppState(app, &testProj, "abc123", app.Spec.Source, false, false, nil) + sources := make([]argoappv1.ApplicationSource, 0) + sources = append(sources, app.Spec.GetSource()) + revisions := make([]string, 0) + revisions = append(revisions, "abc123") + compRes := ctrl.appStateManager.CompareAppState(app, &testProj, revisions, sources, false, false, nil, false) assert.NotNil(t, compRes) assert.NotNil(t, compRes.syncStatus) assert.Equal(t, argoappv1.SyncStatusCodeSynced, compRes.syncStatus.Status) @@ -695,7 +767,11 @@ func TestSignedResponseSignatureRequired(t *testing.T) { // it doesn't matter for our test whether local manifests are valid localManifests := []string{"foobar"} ctrl := newFakeController(&data) - compRes := ctrl.appStateManager.CompareAppState(app, &signedProj, "abc123", app.Spec.Source, false, false, localManifests) + sources := make([]argoappv1.ApplicationSource, 0) + sources = append(sources, app.Spec.GetSource()) + revisions := make([]string, 0) + revisions = append(revisions, "abc123") + compRes := ctrl.appStateManager.CompareAppState(app, &signedProj, revisions, sources, false, false, localManifests, false) assert.NotNil(t, compRes) assert.NotNil(t, compRes.syncStatus) assert.Equal(t, argoappv1.SyncStatusCodeUnknown, compRes.syncStatus.Status) @@ -720,7 +796,11 @@ func TestSignedResponseSignatureRequired(t *testing.T) { managedLiveObjs: make(map[kube.ResourceKey]*unstructured.Unstructured), } ctrl := newFakeController(&data) - compRes := ctrl.appStateManager.CompareAppState(app, &signedProj, "abc123", app.Spec.Source, false, false, nil) + sources := make([]argoappv1.ApplicationSource, 0) + sources = append(sources, app.Spec.GetSource()) + revisions := make([]string, 0) + revisions = append(revisions, "abc123") + compRes := ctrl.appStateManager.CompareAppState(app, &signedProj, revisions, sources, false, false, nil, false) assert.NotNil(t, compRes) assert.NotNil(t, compRes.syncStatus) assert.Equal(t, argoappv1.SyncStatusCodeSynced, compRes.syncStatus.Status) @@ -729,7 +809,7 @@ func TestSignedResponseSignatureRequired(t *testing.T) { assert.Len(t, app.Status.Conditions, 0) } - // Signature required and local manifests supplied and GPG subystem is disabled - sync + // Signature required and local manifests supplied and GPG subsystem is disabled - sync { app := newFakeApp() data := fakeData{ @@ -745,7 +825,11 @@ func TestSignedResponseSignatureRequired(t *testing.T) { // it doesn't matter for our test whether local manifests are valid localManifests := []string{""} ctrl := newFakeController(&data) - compRes := ctrl.appStateManager.CompareAppState(app, &signedProj, "abc123", app.Spec.Source, false, false, localManifests) + sources := make([]argoappv1.ApplicationSource, 0) + sources = append(sources, app.Spec.GetSource()) + revisions := make([]string, 0) + revisions = append(revisions, "abc123") + compRes := ctrl.appStateManager.CompareAppState(app, &signedProj, revisions, sources, false, false, localManifests, false) assert.NotNil(t, compRes) assert.NotNil(t, compRes.syncStatus) assert.Equal(t, argoappv1.SyncStatusCodeSynced, compRes.syncStatus.Status) diff --git a/controller/sync.go b/controller/sync.go index 1c592f5c0a733..65e86851ee364 100644 --- a/controller/sync.go +++ b/controller/sync.go @@ -4,12 +4,13 @@ import ( "context" "encoding/json" "fmt" - cdcommon "github.com/argoproj/argo-cd/v2/common" "os" "strconv" "sync/atomic" "time" + cdcommon "github.com/argoproj/argo-cd/v2/common" + "github.com/argoproj/gitops-engine/pkg/sync" "github.com/argoproj/gitops-engine/pkg/sync/common" "github.com/argoproj/gitops-engine/pkg/utils/kube" @@ -65,6 +66,8 @@ func (m *appStateManager) SyncAppState(app *v1alpha1.Application, state *v1alpha var syncOp v1alpha1.SyncOperation var syncRes *v1alpha1.SyncOperationResult var source v1alpha1.ApplicationSource + var sources []v1alpha1.ApplicationSource + revisions := make([]string, 0) if state.Operation.Sync == nil { state.Phase = common.OperationFailed @@ -82,31 +85,53 @@ func (m *appStateManager) SyncAppState(app *v1alpha1.Application, state *v1alpha return } - if syncOp.Source == nil { - // normal sync case (where source is taken from app.spec.source) - source = app.Spec.Source + if syncOp.Source == nil || (syncOp.Sources != nil && len(syncOp.Sources) > 0) { + // normal sync case (where source is taken from app.spec.sources) + if app.Spec.HasMultipleSources() { + sources = app.Spec.Sources + } else { + // normal sync case (where source is taken from app.spec.source) + source = app.Spec.GetSource() + sources = make([]v1alpha1.ApplicationSource, 0) + } } else { // rollback case - source = *state.Operation.Sync.Source + if app.Spec.HasMultipleSources() { + sources = state.Operation.Sync.Sources + } else { + source = *state.Operation.Sync.Source + sources = make([]v1alpha1.ApplicationSource, 0) + } } if state.SyncResult != nil { syncRes = state.SyncResult revision = state.SyncResult.Revision + revisions = append(revisions, state.SyncResult.Revisions...) } else { syncRes = &v1alpha1.SyncOperationResult{} // status.operationState.syncResult.source. must be set properly since auto-sync relies // on this information to decide if it should sync (if source is different than the last // sync attempt) - syncRes.Source = source + if app.Spec.HasMultipleSources() { + syncRes.Sources = sources + } else { + syncRes.Source = source + } state.SyncResult = syncRes } - if revision == "" { - // if we get here, it means we did not remember a commit SHA which we should be syncing to. - // This typically indicates we are just about to begin a brand new sync/rollback operation. - // Take the value in the requested operation. We will resolve this to a SHA later. - revision = syncOp.Revision + // if we get here, it means we did not remember a commit SHA which we should be syncing to. + // This typically indicates we are just about to begin a brand new sync/rollback operation. + // Take the value in the requested operation. We will resolve this to a SHA later. + if app.Spec.HasMultipleSources() { + if len(revisions) != len(sources) { + revisions = syncOp.Revisions + } + } else { + if revision == "" { + revision = syncOp.Revision + } } proj, err := argo.GetAppProject(app, listersv1alpha1.NewAppProjectLister(m.projInformer.GetIndexer()), m.namespace, m.settingsMgr, m.db, context.TODO()) @@ -116,10 +141,23 @@ func (m *appStateManager) SyncAppState(app *v1alpha1.Application, state *v1alpha return } - compareResult := m.CompareAppState(app, proj, revision, source, false, true, syncOp.Manifests) + if app.Spec.HasMultipleSources() { + revisions = syncRes.Revisions + } else { + revisions = append(revisions, revision) + } + + if !app.Spec.HasMultipleSources() { + sources = []v1alpha1.ApplicationSource{source} + revisions = []string{revision} + } + + compareResult := m.CompareAppState(app, proj, revisions, sources, false, true, syncOp.Manifests, app.Spec.HasMultipleSources()) // We now have a concrete commit SHA. Save this in the sync result revision so that we remember // what we should be syncing to when resuming operations. + syncRes.Revision = compareResult.syncStatus.Revision + syncRes.Revisions = compareResult.syncStatus.Revisions // If there are any comparison or spec errors error conditions do not perform the operation if errConditions := app.Status.GetConditions(map[v1alpha1.ApplicationConditionType]bool{ @@ -302,7 +340,7 @@ func (m *appStateManager) SyncAppState(app *v1alpha1.Application, state *v1alpha logEntry.WithField("duration", time.Since(start)).Info("sync/terminate complete") if !syncOp.DryRun && len(syncOp.Resources) == 0 && state.Phase.Successful() { - err := m.persistRevisionHistory(app, compareResult.syncStatus.Revision, source, state.StartedAt) + err := m.persistRevisionHistory(app, compareResult.syncStatus.Revision, source, compareResult.syncStatus.Revisions, compareResult.syncStatus.ComparedTo.Sources, app.Spec.HasMultipleSources(), state.StartedAt) if err != nil { state.Phase = common.OperationError state.Message = fmt.Sprintf("failed to record sync to history: %v", err) diff --git a/controller/sync_test.go b/controller/sync_test.go index 7694d9a885a1b..13406ddc0cb0e 100644 --- a/controller/sync_test.go +++ b/controller/sync_test.go @@ -50,12 +50,12 @@ func TestPersistRevisionHistory(t *testing.T) { }} ctrl.appStateManager.SyncAppState(app, opState) // Ensure we record spec.source into sync result - assert.Equal(t, app.Spec.Source, opState.SyncResult.Source) + assert.Equal(t, app.Spec.GetSource(), opState.SyncResult.Source) updatedApp, err := ctrl.applicationClientset.ArgoprojV1alpha1().Applications(app.Namespace).Get(context.Background(), app.Name, v1.GetOptions{}) assert.Nil(t, err) assert.Equal(t, 1, len(updatedApp.Status.History)) - assert.Equal(t, app.Spec.Source, updatedApp.Status.History[0].Source) + assert.Equal(t, app.Spec.GetSource(), updatedApp.Status.History[0].Source) assert.Equal(t, "abc123", updatedApp.Status.History[0].Revision) } diff --git a/docs/operator-manual/application.yaml b/docs/operator-manual/application.yaml index 77ae6d0e83aac..c693a581a45ec 100644 --- a/docs/operator-manual/application.yaml +++ b/docs/operator-manual/application.yaml @@ -132,6 +132,13 @@ spec: - name: map-param map: param-name: param-value + + # Sources field specifies the list of sources for the application + sources: + - repoURL: https://github.com/argoproj/argocd-example-apps.git # Can point to either a Helm chart repo or a git repo. + targetRevision: HEAD # For Helm, this refers to the chart version. + path: guestbook # This has no meaning for Helm charts pulled directly from a Helm repo instead of git. + ref: my-repo # For Helm, acts as a reference to this source for fetching values files from this source. Has no meaning when under `source` field # Destination cluster and namespace to deploy the application destination: diff --git a/docs/user-guide/multiple_sources.md b/docs/user-guide/multiple_sources.md new file mode 100644 index 0000000000000..145eef19b619d --- /dev/null +++ b/docs/user-guide/multiple_sources.md @@ -0,0 +1,73 @@ +# Multiple Sources for an Application + +!!! warning "Beta Feature" + Specifying multiple sources for an application is a beta feature. The UI and CLI still generally behave as if only + the first source is specified. Full UI/CLI support will be added in a future release. + This feature is subject to change in backwards incompatible ways until it is marked stable. + +Argo CD has the ability to specify multiple sources for a single Application. Argo CD compiles all the sources +and reconciles the combined resources. + +You can provide multiple sources using the `sources` field. When you specify the `sources` field, Argo CD will ignore +the `source` (singular) field. + +See the below example for specifying multiple sources: + +```yaml +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: guestbook + namespace: argocd +spec: + project: default + destination: + server: https://kubernetes.default.svc + namespace: default + sources: + - chart: elasticsearch + repoURL: https://helm.elastic.co + targetRevision: 7.6.0 + - repoURL: https://github.com/argoproj/argocd-example-apps.git + path: guestbook + targetRevision: HEAD +``` + +The above example has two sources specified. Argo CD will generate the manifests for each source separately and combine +the resulting manifests. + +If multiple sources produce the same resource (same `group`, `kind`, `name`, and `namespace`), the last source to +produce the resource will take precedence. Argo CD will produce a `RepeatedResourceWarning` in this case, but it will +sync the resources. This provides a convenient way to override a resource from a chart with a resource from a Git repo. + +## Helm value files from external Git repository + +Helm sources can reference value files from git sources. This allows you to use a third-party Helm chart with custom, +git-hosted values. + +```yaml +apiVersion: argoproj.io/v1alpha1 +kind: Application +spec: + sources: + - repoURL: 'https://prometheus-community.github.io/helm-charts' + chart: prometheus + targetRevision: 15.7.1 + helm: + valueFiles: + - $values/charts/prometheus/values.yaml + - repoURL: 'https://git.example.gom/org/value-files.git' + targetRevision: dev + ref: values +``` + +In the above example, the `prometheus` chart will use the value file from `git.example.gom/org/value-files.git`. +`$values` resolves to the root of the `value-files` repository. The `$values` variable may only be specified at the +beginning of the value file path. + +If the `path` field is set in the `$values` source, Argo CD will attempt to generate resources from the git repository +at that URL. If the `path` field is not set, Argo CD will use the repository solely as a source of value files. + +!!! note + Sources with the `ref` field set must not also specify the `chart` field. Argo CD does not currently support using + another Helm chart as a source for value files. diff --git a/hack/gen-resources/generators/application_generator.go b/hack/gen-resources/generators/application_generator.go index 7810513faea79..b19280ae688b9 100644 --- a/hack/gen-resources/generators/application_generator.go +++ b/hack/gen-resources/generators/application_generator.go @@ -98,7 +98,7 @@ func (pg *ApplicationGenerator) Generate(opts *util.GenerateOpts) error { Spec: v1alpha1.ApplicationSpec{ Project: "default", Destination: *destination, - Source: *source, + Source: source, }, }, v1.CreateOptions{}) if err != nil { diff --git a/manifests/core-install.yaml b/manifests/core-install.yaml index 1f9a35cf75579..87ce640966327 100644 --- a/manifests/core-install.yaml +++ b/manifests/core-install.yaml @@ -144,6 +144,14 @@ spec: which to sync the application to If omitted, will use the revision specified in app spec. type: string + revisions: + description: Revisions is the list of revision (Git) or chart + version (Helm) which to sync each source in sources field for + the application to If omitted, will use the revision specified + in app spec. + items: + type: string + type: array source: description: Source overrides the source definition set in the application. This is typically set in a Rollback operation and @@ -383,6 +391,11 @@ spec: type: object type: array type: object + ref: + description: Ref is reference to another source within sources + field. This field will not be used if used with a `source` + tag. + type: string repoURL: description: RepoURL is the URL to the repository (Git or Helm) that contains the application manifests @@ -396,510 +409,1042 @@ spec: required: - repoURL type: object - syncOptions: - description: SyncOptions provide per-sync sync-options, e.g. Validate=false + sources: + description: Sources overrides the source definition set in the + application. This is typically set in a Rollback operation and + is nil during a Sync operation items: - type: string - type: array - syncStrategy: - description: SyncStrategy describes how to perform the sync - properties: - apply: - description: Apply will perform a `kubectl apply` to perform - the sync. - properties: - force: - description: Force indicates whether or not to supply - the --force flag to `kubectl apply`. The --force flag - deletes and re-create the resource, when PATCH encounters - conflict and has retried for 5 times. - type: boolean - type: object - hook: - description: Hook will submit any referenced resources to - perform the sync. This is the default strategy - properties: - force: - description: Force indicates whether or not to supply - the --force flag to `kubectl apply`. The --force flag - deletes and re-create the resource, when PATCH encounters - conflict and has retried for 5 times. - type: boolean - type: object - type: object - type: object - type: object - spec: - description: ApplicationSpec represents desired application state. Contains - link to repository with application definition and additional parameters - link definition revision. - properties: - destination: - description: Destination is a reference to the target Kubernetes server - and namespace - properties: - name: - description: Name is an alternate way of specifying the target - cluster by its symbolic name - type: string - namespace: - description: Namespace specifies the target namespace for the - application's resources. The namespace will only be set for - namespace-scoped resources that have not set a value for .metadata.namespace - type: string - server: - description: Server specifies the URL of the target cluster and - must be set to the Kubernetes control plane API - type: string - type: object - ignoreDifferences: - description: IgnoreDifferences is a list of resources and their fields - which should be ignored during comparison - items: - description: ResourceIgnoreDifferences contains resource filter - and list of json paths which should be ignored during comparison - with live state. - properties: - group: - type: string - jqPathExpressions: - items: - type: string - type: array - jsonPointers: - items: - type: string - type: array - kind: - type: string - managedFieldsManagers: - description: ManagedFieldsManagers is a list of trusted managers. - Fields mutated by those managers will take precedence over - the desired state defined in the SCM and won't be displayed - in diffs - items: - type: string - type: array - name: - type: string - namespace: - type: string - required: - - kind - type: object - type: array - info: - description: Info contains a list of information (URLs, email addresses, - and plain text) that relates to the application - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - project: - description: Project is a reference to the project this application - belongs to. The empty string means that application belongs to the - 'default' project. - type: string - revisionHistoryLimit: - description: RevisionHistoryLimit limits the number of items kept - in the application's revision history, which is used for informational - purposes as well as for rollbacks to previous versions. This should - only be changed in exceptional circumstances. Setting to zero will - store no history. This will reduce storage used. Increasing will - increase the space used to store the history, so we do not recommend - increasing it. Default is 10. - format: int64 - type: integer - source: - description: Source is a reference to the location of the application's - manifests or chart - properties: - chart: - description: Chart is a Helm chart name, and must be specified - for applications sourced from a Helm repo. - type: string - directory: - description: Directory holds path/directory specific options - properties: - exclude: - description: Exclude contains a glob pattern to match paths - against that should be explicitly excluded from being used - during manifest generation - type: string - include: - description: Include contains a glob pattern to match paths - against that should be explicitly included during manifest - generation - type: string - jsonnet: - description: Jsonnet holds options specific to Jsonnet - properties: - extVars: - description: ExtVars is a list of Jsonnet External Variables - items: - description: JsonnetVar represents a variable to be - passed to jsonnet during manifest generation - properties: - code: - type: boolean - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - libs: - description: Additional library search dirs - items: - type: string - type: array - tlas: - description: TLAS is a list of Jsonnet Top-level Arguments - items: - description: JsonnetVar represents a variable to be - passed to jsonnet during manifest generation - properties: - code: - type: boolean - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - type: object - recurse: - description: Recurse specifies whether to scan a directory - recursively for manifests - type: boolean - type: object - helm: - description: Helm holds helm specific options - properties: - fileParameters: - description: FileParameters are file parameters to the helm - template - items: - description: HelmFileParameter is a file parameter that's - passed to helm template during manifest generation - properties: - name: - description: Name is the name of the Helm parameter - type: string - path: - description: Path is the path to the file containing - the values for the Helm parameter - type: string - type: object - type: array - ignoreMissingValueFiles: - description: IgnoreMissingValueFiles prevents helm template - from failing when valueFiles do not exist locally by not - appending them to helm template --values - type: boolean - parameters: - description: Parameters is a list of Helm parameters which - are passed to the helm template command upon manifest generation - items: - description: HelmParameter is a parameter that's passed - to helm template during manifest generation + description: ApplicationSource contains all required information + about the source of an application + properties: + chart: + description: Chart is a Helm chart name, and must be specified + for applications sourced from a Helm repo. + type: string + directory: + description: Directory holds path/directory specific options properties: - forceString: - description: ForceString determines whether to tell - Helm to interpret booleans and numbers as strings - type: boolean - name: - description: Name is the name of the Helm parameter + exclude: + description: Exclude contains a glob pattern to match + paths against that should be explicitly excluded from + being used during manifest generation type: string - value: - description: Value is the value for the Helm parameter + include: + description: Include contains a glob pattern to match + paths against that should be explicitly included during + manifest generation type: string - type: object - type: array - passCredentials: - description: PassCredentials pass credentials to all domains - (Helm's --pass-credentials) - type: boolean - releaseName: - description: ReleaseName is the Helm release name to use. - If omitted it will use the application name - type: string - skipCrds: - description: SkipCrds skips custom resource definition installation - step (Helm's --skip-crds) - type: boolean - valueFiles: - description: ValuesFiles is a list of Helm value files to - use when generating a template - items: - type: string - type: array - values: - description: Values specifies Helm values to be passed to - helm template, typically defined as a block - type: string - version: - description: Version is the Helm version to use for templating - ("3") - type: string - type: object - kustomize: - description: Kustomize holds kustomize specific options - properties: - commonAnnotations: - additionalProperties: - type: string - description: CommonAnnotations is a list of additional annotations - to add to rendered manifests - type: object - commonLabels: - additionalProperties: - type: string - description: CommonLabels is a list of additional labels to - add to rendered manifests - type: object - forceCommonAnnotations: - description: ForceCommonAnnotations specifies whether to force - applying common annotations to resources for Kustomize apps - type: boolean - forceCommonLabels: - description: ForceCommonLabels specifies whether to force - applying common labels to resources for Kustomize apps - type: boolean - images: - description: Images is a list of Kustomize image override - specifications - items: - description: KustomizeImage represents a Kustomize image - definition in the format [old_image_name=]: - type: string - type: array - namePrefix: - description: NamePrefix is a prefix appended to resources - for Kustomize apps - type: string - nameSuffix: - description: NameSuffix is a suffix appended to resources - for Kustomize apps - type: string - version: - description: Version controls which version of Kustomize to - use for rendering manifests - type: string - type: object - path: - description: Path is a directory path within the Git repository, - and is only valid for applications sourced from Git. - type: string - plugin: - description: Plugin holds config management plugin specific options - properties: - env: - description: Env is a list of environment variable entries - items: - description: EnvEntry represents an entry in the application's - environment + jsonnet: + description: Jsonnet holds options specific to Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet External + Variables + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level + Arguments + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan a directory + recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options properties: - name: - description: Name is the name of the variable, usually - expressed in uppercase + fileParameters: + description: FileParameters are file parameters to the + helm template + items: + description: HelmFileParameter is a file parameter + that's passed to helm template during manifest generation + properties: + name: + description: Name is the name of the Helm parameter + type: string + path: + description: Path is the path to the file containing + the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents helm template + from failing when valueFiles do not exist locally + by not appending them to helm template --values + type: boolean + parameters: + description: Parameters is a list of Helm parameters + which are passed to the helm template command upon + manifest generation + items: + description: HelmParameter is a parameter that's passed + to helm template during manifest generation + properties: + forceString: + description: ForceString determines whether to + tell Helm to interpret booleans and numbers + as strings + type: boolean + name: + description: Name is the name of the Helm parameter + type: string + value: + description: Value is the value for the Helm parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials to all + domains (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release name to + use. If omitted it will use the application name type: string - value: - description: Value is the value of the variable + skipCrds: + description: SkipCrds skips custom resource definition + installation step (Helm's --skip-crds) + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value files + to use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to be passed + to helm template, typically defined as a block + type: string + version: + description: Version is the Helm version to use for + templating ("3") type: string - required: - - name - - value type: object - type: array - name: - type: string - parameters: - items: + kustomize: + description: Kustomize holds kustomize specific options properties: - array: - description: Array is the value of an array type parameter. - items: + commonAnnotations: + additionalProperties: type: string - type: array - map: + description: CommonAnnotations is a list of additional + annotations to add to rendered manifests + type: object + commonLabels: additionalProperties: type: string - description: Map is the value of a map type parameter. + description: CommonLabels is a list of additional labels + to add to rendered manifests type: object - name: - description: Name is the name identifying a parameter. + forceCommonAnnotations: + description: ForceCommonAnnotations specifies whether + to force applying common annotations to resources + for Kustomize apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether to + force applying common labels to resources for Kustomize + apps + type: boolean + images: + description: Images is a list of Kustomize image override + specifications + items: + description: KustomizeImage represents a Kustomize + image definition in the format [old_image_name=]: + type: string + type: array + namePrefix: + description: NamePrefix is a prefix appended to resources + for Kustomize apps type: string - string: - description: String_ is the value of a string type parameter. + nameSuffix: + description: NameSuffix is a suffix appended to resources + for Kustomize apps + type: string + version: + description: Version controls which version of Kustomize + to use for rendering manifests type: string type: object - type: array - type: object - repoURL: - description: RepoURL is the URL to the repository (Git or Helm) - that contains the application manifests - type: string - targetRevision: - description: TargetRevision defines the revision of the source - to sync the application to. In case of Git, this can be commit, - tag, or branch. If omitted, will equal to HEAD. In case of Helm, - this is a semver tag for the Chart's version. - type: string - required: - - repoURL - type: object - syncPolicy: - description: SyncPolicy controls when and how a sync will be performed - properties: - automated: - description: Automated will keep an application synced to the - target revision - properties: - allowEmpty: - description: 'AllowEmpty allows apps have zero live resources - (default: false)' - type: boolean - prune: - description: 'Prune specifies whether to delete resources - from the cluster that are not found in the sources anymore - as part of automated sync (default: false)' - type: boolean - selfHeal: - description: 'SelfHeal specifes whether to revert resources - back to their desired state upon modification in the cluster - (default: false)' - type: boolean - type: object - managedNamespaceMetadata: - description: ManagedNamespaceMetadata controls metadata in the - given namespace (if CreateNamespace=true) - properties: - annotations: - additionalProperties: + path: + description: Path is a directory path within the Git repository, + and is only valid for applications sourced from Git. type: string - type: object - labels: - additionalProperties: + plugin: + description: Plugin holds config management plugin specific + options + properties: + env: + description: Env is a list of environment variable entries + items: + description: EnvEntry represents an entry in the application's + environment + properties: + name: + description: Name is the name of the variable, + usually expressed in uppercase + type: string + value: + description: Value is the value of the variable + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + description: Array is the value of an array type + parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map type parameter. + type: object + name: + description: Name is the name identifying a parameter. + type: string + string: + description: String_ is the value of a string + type parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source within sources + field. This field will not be used if used with a `source` + tag. type: string - type: object - type: object - retry: - description: Retry controls failed sync retry behavior - properties: - backoff: - description: Backoff controls how to backoff on subsequent - retries of failed syncs - properties: - duration: - description: Duration is the amount to back off. Default - unit is seconds, but could also be a duration (e.g. - "2m", "1h") - type: string - factor: - description: Factor is a factor to multiply the base duration - after each failed retry - format: int64 - type: integer - maxDuration: - description: MaxDuration is the maximum amount of time - allowed for the backoff strategy - type: string - type: object - limit: - description: Limit is the maximum number of attempts for retrying - a failed sync. If set to 0, no retries will be performed. - format: int64 - type: integer - type: object + repoURL: + description: RepoURL is the URL to the repository (Git or + Helm) that contains the application manifests + type: string + targetRevision: + description: TargetRevision defines the revision of the + source to sync the application to. In case of Git, this + can be commit, tag, or branch. If omitted, will equal + to HEAD. In case of Helm, this is a semver tag for the + Chart's version. + type: string + required: + - repoURL + type: object + type: array syncOptions: - description: Options allow you to specify whole app sync-options + description: SyncOptions provide per-sync sync-options, e.g. Validate=false items: type: string type: array + syncStrategy: + description: SyncStrategy describes how to perform the sync + properties: + apply: + description: Apply will perform a `kubectl apply` to perform + the sync. + properties: + force: + description: Force indicates whether or not to supply + the --force flag to `kubectl apply`. The --force flag + deletes and re-create the resource, when PATCH encounters + conflict and has retried for 5 times. + type: boolean + type: object + hook: + description: Hook will submit any referenced resources to + perform the sync. This is the default strategy + properties: + force: + description: Force indicates whether or not to supply + the --force flag to `kubectl apply`. The --force flag + deletes and re-create the resource, when PATCH encounters + conflict and has retried for 5 times. + type: boolean + type: object + type: object type: object - required: - - destination - - project - - source type: object - status: - description: ApplicationStatus contains status information for the application + spec: + description: ApplicationSpec represents desired application state. Contains + link to repository with application definition and additional parameters + link definition revision. properties: - conditions: - description: Conditions is a list of currently observed application - conditions - items: - description: ApplicationCondition contains details about an application - condition, which is usally an error or warning - properties: - lastTransitionTime: - description: LastTransitionTime is the time the condition was - last observed - format: date-time - type: string - message: - description: Message contains human-readable message indicating - details about condition - type: string - type: - description: Type is an application condition type - type: string - required: - - message - - type - type: object - type: array - health: - description: Health contains information about the application's current - health status + destination: + description: Destination is a reference to the target Kubernetes server + and namespace properties: - message: - description: Message is a human-readable informational message - describing the health status + name: + description: Name is an alternate way of specifying the target + cluster by its symbolic name type: string - status: - description: Status holds the status code of the application or - resource + namespace: + description: Namespace specifies the target namespace for the + application's resources. The namespace will only be set for + namespace-scoped resources that have not set a value for .metadata.namespace + type: string + server: + description: Server specifies the URL of the target cluster and + must be set to the Kubernetes control plane API type: string type: object - history: - description: History contains information about the application's - sync history + ignoreDifferences: + description: IgnoreDifferences is a list of resources and their fields + which should be ignored during comparison items: - description: RevisionHistory contains history information about - a previous sync + description: ResourceIgnoreDifferences contains resource filter + and list of json paths which should be ignored during comparison + with live state. properties: - deployStartedAt: - description: DeployStartedAt holds the time the sync operation - started - format: date-time + group: type: string - deployedAt: - description: DeployedAt holds the time the sync operation completed - format: date-time + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: type: string - id: - description: ID is an auto incrementing identifier of the RevisionHistory + managedFieldsManagers: + description: ManagedFieldsManagers is a list of trusted managers. + Fields mutated by those managers will take precedence over + the desired state defined in the SCM and won't be displayed + in diffs + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + description: Info contains a list of information (URLs, email addresses, + and plain text) that relates to the application + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + description: Project is a reference to the project this application + belongs to. The empty string means that application belongs to the + 'default' project. + type: string + revisionHistoryLimit: + description: RevisionHistoryLimit limits the number of items kept + in the application's revision history, which is used for informational + purposes as well as for rollbacks to previous versions. This should + only be changed in exceptional circumstances. Setting to zero will + store no history. This will reduce storage used. Increasing will + increase the space used to store the history, so we do not recommend + increasing it. Default is 10. + format: int64 + type: integer + source: + description: Source is a reference to the location of the application's + manifests or chart + properties: + chart: + description: Chart is a Helm chart name, and must be specified + for applications sourced from a Helm repo. + type: string + directory: + description: Directory holds path/directory specific options + properties: + exclude: + description: Exclude contains a glob pattern to match paths + against that should be explicitly excluded from being used + during manifest generation + type: string + include: + description: Include contains a glob pattern to match paths + against that should be explicitly included during manifest + generation + type: string + jsonnet: + description: Jsonnet holds options specific to Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet External Variables + items: + description: JsonnetVar represents a variable to be + passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level Arguments + items: + description: JsonnetVar represents a variable to be + passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan a directory + recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options + properties: + fileParameters: + description: FileParameters are file parameters to the helm + template + items: + description: HelmFileParameter is a file parameter that's + passed to helm template during manifest generation + properties: + name: + description: Name is the name of the Helm parameter + type: string + path: + description: Path is the path to the file containing + the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents helm template + from failing when valueFiles do not exist locally by not + appending them to helm template --values + type: boolean + parameters: + description: Parameters is a list of Helm parameters which + are passed to the helm template command upon manifest generation + items: + description: HelmParameter is a parameter that's passed + to helm template during manifest generation + properties: + forceString: + description: ForceString determines whether to tell + Helm to interpret booleans and numbers as strings + type: boolean + name: + description: Name is the name of the Helm parameter + type: string + value: + description: Value is the value for the Helm parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials to all domains + (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release name to use. + If omitted it will use the application name + type: string + skipCrds: + description: SkipCrds skips custom resource definition installation + step (Helm's --skip-crds) + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value files to + use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to be passed to + helm template, typically defined as a block + type: string + version: + description: Version is the Helm version to use for templating + ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific options + properties: + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of additional annotations + to add to rendered manifests + type: object + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional labels to + add to rendered manifests + type: object + forceCommonAnnotations: + description: ForceCommonAnnotations specifies whether to force + applying common annotations to resources for Kustomize apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether to force + applying common labels to resources for Kustomize apps + type: boolean + images: + description: Images is a list of Kustomize image override + specifications + items: + description: KustomizeImage represents a Kustomize image + definition in the format [old_image_name=]: + type: string + type: array + namePrefix: + description: NamePrefix is a prefix appended to resources + for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended to resources + for Kustomize apps + type: string + version: + description: Version controls which version of Kustomize to + use for rendering manifests + type: string + type: object + path: + description: Path is a directory path within the Git repository, + and is only valid for applications sourced from Git. + type: string + plugin: + description: Plugin holds config management plugin specific options + properties: + env: + description: Env is a list of environment variable entries + items: + description: EnvEntry represents an entry in the application's + environment + properties: + name: + description: Name is the name of the variable, usually + expressed in uppercase + type: string + value: + description: Value is the value of the variable + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + description: Array is the value of an array type parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map type parameter. + type: object + name: + description: Name is the name identifying a parameter. + type: string + string: + description: String_ is the value of a string type parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source within sources + field. This field will not be used if used with a `source` tag. + type: string + repoURL: + description: RepoURL is the URL to the repository (Git or Helm) + that contains the application manifests + type: string + targetRevision: + description: TargetRevision defines the revision of the source + to sync the application to. In case of Git, this can be commit, + tag, or branch. If omitted, will equal to HEAD. In case of Helm, + this is a semver tag for the Chart's version. + type: string + required: + - repoURL + type: object + sources: + description: Sources is a reference to the location of the application's + manifests or chart + items: + description: ApplicationSource contains all required information + about the source of an application + properties: + chart: + description: Chart is a Helm chart name, and must be specified + for applications sourced from a Helm repo. + type: string + directory: + description: Directory holds path/directory specific options + properties: + exclude: + description: Exclude contains a glob pattern to match paths + against that should be explicitly excluded from being + used during manifest generation + type: string + include: + description: Include contains a glob pattern to match paths + against that should be explicitly included during manifest + generation + type: string + jsonnet: + description: Jsonnet holds options specific to Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet External Variables + items: + description: JsonnetVar represents a variable to be + passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level Arguments + items: + description: JsonnetVar represents a variable to be + passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan a directory + recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options + properties: + fileParameters: + description: FileParameters are file parameters to the helm + template + items: + description: HelmFileParameter is a file parameter that's + passed to helm template during manifest generation + properties: + name: + description: Name is the name of the Helm parameter + type: string + path: + description: Path is the path to the file containing + the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents helm template + from failing when valueFiles do not exist locally by not + appending them to helm template --values + type: boolean + parameters: + description: Parameters is a list of Helm parameters which + are passed to the helm template command upon manifest + generation + items: + description: HelmParameter is a parameter that's passed + to helm template during manifest generation + properties: + forceString: + description: ForceString determines whether to tell + Helm to interpret booleans and numbers as strings + type: boolean + name: + description: Name is the name of the Helm parameter + type: string + value: + description: Value is the value for the Helm parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials to all domains + (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release name to use. + If omitted it will use the application name + type: string + skipCrds: + description: SkipCrds skips custom resource definition installation + step (Helm's --skip-crds) + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value files to + use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to be passed to + helm template, typically defined as a block + type: string + version: + description: Version is the Helm version to use for templating + ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific options + properties: + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of additional annotations + to add to rendered manifests + type: object + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional labels + to add to rendered manifests + type: object + forceCommonAnnotations: + description: ForceCommonAnnotations specifies whether to + force applying common annotations to resources for Kustomize + apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether to force + applying common labels to resources for Kustomize apps + type: boolean + images: + description: Images is a list of Kustomize image override + specifications + items: + description: KustomizeImage represents a Kustomize image + definition in the format [old_image_name=]: + type: string + type: array + namePrefix: + description: NamePrefix is a prefix appended to resources + for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended to resources + for Kustomize apps + type: string + version: + description: Version controls which version of Kustomize + to use for rendering manifests + type: string + type: object + path: + description: Path is a directory path within the Git repository, + and is only valid for applications sourced from Git. + type: string + plugin: + description: Plugin holds config management plugin specific + options + properties: + env: + description: Env is a list of environment variable entries + items: + description: EnvEntry represents an entry in the application's + environment + properties: + name: + description: Name is the name of the variable, usually + expressed in uppercase + type: string + value: + description: Value is the value of the variable + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + description: Array is the value of an array type parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map type parameter. + type: object + name: + description: Name is the name identifying a parameter. + type: string + string: + description: String_ is the value of a string type + parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source within sources + field. This field will not be used if used with a `source` + tag. + type: string + repoURL: + description: RepoURL is the URL to the repository (Git or Helm) + that contains the application manifests + type: string + targetRevision: + description: TargetRevision defines the revision of the source + to sync the application to. In case of Git, this can be commit, + tag, or branch. If omitted, will equal to HEAD. In case of + Helm, this is a semver tag for the Chart's version. + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + description: SyncPolicy controls when and how a sync will be performed + properties: + automated: + description: Automated will keep an application synced to the + target revision + properties: + allowEmpty: + description: 'AllowEmpty allows apps have zero live resources + (default: false)' + type: boolean + prune: + description: 'Prune specifies whether to delete resources + from the cluster that are not found in the sources anymore + as part of automated sync (default: false)' + type: boolean + selfHeal: + description: 'SelfHeal specifes whether to revert resources + back to their desired state upon modification in the cluster + (default: false)' + type: boolean + type: object + managedNamespaceMetadata: + description: ManagedNamespaceMetadata controls metadata in the + given namespace (if CreateNamespace=true) + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + description: Retry controls failed sync retry behavior + properties: + backoff: + description: Backoff controls how to backoff on subsequent + retries of failed syncs + properties: + duration: + description: Duration is the amount to back off. Default + unit is seconds, but could also be a duration (e.g. + "2m", "1h") + type: string + factor: + description: Factor is a factor to multiply the base duration + after each failed retry + format: int64 + type: integer + maxDuration: + description: MaxDuration is the maximum amount of time + allowed for the backoff strategy + type: string + type: object + limit: + description: Limit is the maximum number of attempts for retrying + a failed sync. If set to 0, no retries will be performed. + format: int64 + type: integer + type: object + syncOptions: + description: Options allow you to specify whole app sync-options + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + status: + description: ApplicationStatus contains status information for the application + properties: + conditions: + description: Conditions is a list of currently observed application + conditions + items: + description: ApplicationCondition contains details about an application + condition, which is usally an error or warning + properties: + lastTransitionTime: + description: LastTransitionTime is the time the condition was + last observed + format: date-time + type: string + message: + description: Message contains human-readable message indicating + details about condition + type: string + type: + description: Type is an application condition type + type: string + required: + - message + - type + type: object + type: array + health: + description: Health contains information about the application's current + health status + properties: + message: + description: Message is a human-readable informational message + describing the health status + type: string + status: + description: Status holds the status code of the application or + resource + type: string + type: object + history: + description: History contains information about the application's + sync history + items: + description: RevisionHistory contains history information about + a previous sync + properties: + deployStartedAt: + description: DeployStartedAt holds the time the sync operation + started + format: date-time + type: string + deployedAt: + description: DeployedAt holds the time the sync operation completed + format: date-time + type: string + id: + description: ID is an auto incrementing identifier of the RevisionHistory format: int64 type: integer revision: description: Revision holds the revision the sync was performed against type: string + revisions: + description: Revisions holds the revision of each source in + sources field the sync was performed against + items: + type: string + type: array source: description: Source is a reference to the application source used for the sync operation @@ -1016,149 +1561,422 @@ spec: type: string type: object type: array - passCredentials: - description: PassCredentials pass credentials to all - domains (Helm's --pass-credentials) - type: boolean - releaseName: - description: ReleaseName is the Helm release name to - use. If omitted it will use the application name + passCredentials: + description: PassCredentials pass credentials to all + domains (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release name to + use. If omitted it will use the application name + type: string + skipCrds: + description: SkipCrds skips custom resource definition + installation step (Helm's --skip-crds) + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value files + to use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to be passed + to helm template, typically defined as a block + type: string + version: + description: Version is the Helm version to use for + templating ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific options + properties: + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of additional + annotations to add to rendered manifests + type: object + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional labels + to add to rendered manifests + type: object + forceCommonAnnotations: + description: ForceCommonAnnotations specifies whether + to force applying common annotations to resources + for Kustomize apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether to + force applying common labels to resources for Kustomize + apps + type: boolean + images: + description: Images is a list of Kustomize image override + specifications + items: + description: KustomizeImage represents a Kustomize + image definition in the format [old_image_name=]: + type: string + type: array + namePrefix: + description: NamePrefix is a prefix appended to resources + for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended to resources + for Kustomize apps + type: string + version: + description: Version controls which version of Kustomize + to use for rendering manifests + type: string + type: object + path: + description: Path is a directory path within the Git repository, + and is only valid for applications sourced from Git. + type: string + plugin: + description: Plugin holds config management plugin specific + options + properties: + env: + description: Env is a list of environment variable entries + items: + description: EnvEntry represents an entry in the application's + environment + properties: + name: + description: Name is the name of the variable, + usually expressed in uppercase + type: string + value: + description: Value is the value of the variable + type: string + required: + - name + - value + type: object + type: array + name: type: string - skipCrds: - description: SkipCrds skips custom resource definition - installation step (Helm's --skip-crds) - type: boolean - valueFiles: - description: ValuesFiles is a list of Helm value files - to use when generating a template + parameters: items: - type: string + properties: + array: + description: Array is the value of an array type + parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map type parameter. + type: object + name: + description: Name is the name identifying a parameter. + type: string + string: + description: String_ is the value of a string + type parameter. + type: string + type: object type: array - values: - description: Values specifies Helm values to be passed - to helm template, typically defined as a block - type: string - version: - description: Version is the Helm version to use for - templating ("3") - type: string type: object - kustomize: - description: Kustomize holds kustomize specific options - properties: - commonAnnotations: - additionalProperties: + ref: + description: Ref is reference to another source within sources + field. This field will not be used if used with a `source` + tag. + type: string + repoURL: + description: RepoURL is the URL to the repository (Git or + Helm) that contains the application manifests + type: string + targetRevision: + description: TargetRevision defines the revision of the + source to sync the application to. In case of Git, this + can be commit, tag, or branch. If omitted, will equal + to HEAD. In case of Helm, this is a semver tag for the + Chart's version. + type: string + required: + - repoURL + type: object + sources: + description: Sources is a reference to the application sources + used for the sync operation + items: + description: ApplicationSource contains all required information + about the source of an application + properties: + chart: + description: Chart is a Helm chart name, and must be specified + for applications sourced from a Helm repo. + type: string + directory: + description: Directory holds path/directory specific options + properties: + exclude: + description: Exclude contains a glob pattern to match + paths against that should be explicitly excluded + from being used during manifest generation type: string - description: CommonAnnotations is a list of additional - annotations to add to rendered manifests - type: object - commonLabels: - additionalProperties: + include: + description: Include contains a glob pattern to match + paths against that should be explicitly included + during manifest generation + type: string + jsonnet: + description: Jsonnet holds options specific to Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet External + Variables + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level + Arguments + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan a directory + recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options + properties: + fileParameters: + description: FileParameters are file parameters to + the helm template + items: + description: HelmFileParameter is a file parameter + that's passed to helm template during manifest + generation + properties: + name: + description: Name is the name of the Helm parameter + type: string + path: + description: Path is the path to the file containing + the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents helm + template from failing when valueFiles do not exist + locally by not appending them to helm template --values + type: boolean + parameters: + description: Parameters is a list of Helm parameters + which are passed to the helm template command upon + manifest generation + items: + description: HelmParameter is a parameter that's + passed to helm template during manifest generation + properties: + forceString: + description: ForceString determines whether + to tell Helm to interpret booleans and numbers + as strings + type: boolean + name: + description: Name is the name of the Helm parameter + type: string + value: + description: Value is the value for the Helm + parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials to all + domains (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release name + to use. If omitted it will use the application name + type: string + skipCrds: + description: SkipCrds skips custom resource definition + installation step (Helm's --skip-crds) + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value files + to use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to be passed + to helm template, typically defined as a block + type: string + version: + description: Version is the Helm version to use for + templating ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific options + properties: + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of additional + annotations to add to rendered manifests + type: object + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional + labels to add to rendered manifests + type: object + forceCommonAnnotations: + description: ForceCommonAnnotations specifies whether + to force applying common annotations to resources + for Kustomize apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether to + force applying common labels to resources for Kustomize + apps + type: boolean + images: + description: Images is a list of Kustomize image override + specifications + items: + description: KustomizeImage represents a Kustomize + image definition in the format [old_image_name=]: + type: string + type: array + namePrefix: + description: NamePrefix is a prefix appended to resources + for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended to resources + for Kustomize apps + type: string + version: + description: Version controls which version of Kustomize + to use for rendering manifests type: string - description: CommonLabels is a list of additional labels - to add to rendered manifests - type: object - forceCommonAnnotations: - description: ForceCommonAnnotations specifies whether - to force applying common annotations to resources - for Kustomize apps - type: boolean - forceCommonLabels: - description: ForceCommonLabels specifies whether to - force applying common labels to resources for Kustomize - apps - type: boolean - images: - description: Images is a list of Kustomize image override - specifications - items: - description: KustomizeImage represents a Kustomize - image definition in the format [old_image_name=]: + type: object + path: + description: Path is a directory path within the Git repository, + and is only valid for applications sourced from Git. + type: string + plugin: + description: Plugin holds config management plugin specific + options + properties: + env: + description: Env is a list of environment variable + entries + items: + description: EnvEntry represents an entry in the + application's environment + properties: + name: + description: Name is the name of the variable, + usually expressed in uppercase + type: string + value: + description: Value is the value of the variable + type: string + required: + - name + - value + type: object + type: array + name: type: string - type: array - namePrefix: - description: NamePrefix is a prefix appended to resources - for Kustomize apps - type: string - nameSuffix: - description: NameSuffix is a suffix appended to resources - for Kustomize apps - type: string - version: - description: Version controls which version of Kustomize - to use for rendering manifests - type: string - type: object - path: - description: Path is a directory path within the Git repository, - and is only valid for applications sourced from Git. - type: string - plugin: - description: Plugin holds config management plugin specific - options - properties: - env: - description: Env is a list of environment variable entries - items: - description: EnvEntry represents an entry in the application's - environment - properties: - name: - description: Name is the name of the variable, - usually expressed in uppercase - type: string - value: - description: Value is the value of the variable - type: string - required: - - name - - value - type: object - type: array - name: - type: string - parameters: - items: - properties: - array: - description: Array is the value of an array type - parameter. - items: + parameters: + items: + properties: + array: + description: Array is the value of an array + type parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map type + parameter. + type: object + name: + description: Name is the name identifying a + parameter. type: string - type: array - map: - additionalProperties: + string: + description: String_ is the value of a string + type parameter. type: string - description: Map is the value of a map type parameter. - type: object - name: - description: Name is the name identifying a parameter. - type: string - string: - description: String_ is the value of a string - type parameter. - type: string - type: object - type: array - type: object - repoURL: - description: RepoURL is the URL to the repository (Git or - Helm) that contains the application manifests - type: string - targetRevision: - description: TargetRevision defines the revision of the - source to sync the application to. In case of Git, this - can be commit, tag, or branch. If omitted, will equal - to HEAD. In case of Helm, this is a semver tag for the - Chart's version. - type: string - required: - - repoURL - type: object + type: object + type: array + type: object + ref: + description: Ref is reference to another source within + sources field. This field will not be used if used with + a `source` tag. + type: string + repoURL: + description: RepoURL is the URL to the repository (Git + or Helm) that contains the application manifests + type: string + targetRevision: + description: TargetRevision defines the revision of the + source to sync the application to. In case of Git, this + can be commit, tag, or branch. If omitted, will equal + to HEAD. In case of Helm, this is a semver tag for the + Chart's version. + type: string + required: + - repoURL + type: object + type: array required: - deployedAt - id - - revision type: object type: array observedAt: @@ -1281,6 +2099,14 @@ spec: (Helm) which to sync the application to If omitted, will use the revision specified in app spec. type: string + revisions: + description: Revisions is the list of revision (Git) or + chart version (Helm) which to sync each source in sources + field for the application to If omitted, will use the + revision specified in app spec. + items: + type: string + type: array source: description: Source overrides the source definition set in the application. This is typically set in a Rollback @@ -1539,6 +2365,11 @@ spec: type: object type: array type: object + ref: + description: Ref is reference to another source within + sources field. This field will not be used if used + with a `source` tag. + type: string repoURL: description: RepoURL is the URL to the repository (Git or Helm) that contains the application manifests @@ -1553,6 +2384,291 @@ spec: required: - repoURL type: object + sources: + description: Sources overrides the source definition set + in the application. This is typically set in a Rollback + operation and is nil during a Sync operation + items: + description: ApplicationSource contains all required + information about the source of an application + properties: + chart: + description: Chart is a Helm chart name, and must + be specified for applications sourced from a Helm + repo. + type: string + directory: + description: Directory holds path/directory specific + options + properties: + exclude: + description: Exclude contains a glob pattern + to match paths against that should be explicitly + excluded from being used during manifest generation + type: string + include: + description: Include contains a glob pattern + to match paths against that should be explicitly + included during manifest generation + type: string + jsonnet: + description: Jsonnet holds options specific + to Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet + External Variables + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest + generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level + Arguments + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest + generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan + a directory recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options + properties: + fileParameters: + description: FileParameters are file parameters + to the helm template + items: + description: HelmFileParameter is a file parameter + that's passed to helm template during manifest + generation + properties: + name: + description: Name is the name of the Helm + parameter + type: string + path: + description: Path is the path to the file + containing the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents + helm template from failing when valueFiles + do not exist locally by not appending them + to helm template --values + type: boolean + parameters: + description: Parameters is a list of Helm parameters + which are passed to the helm template command + upon manifest generation + items: + description: HelmParameter is a parameter + that's passed to helm template during manifest + generation + properties: + forceString: + description: ForceString determines whether + to tell Helm to interpret booleans and + numbers as strings + type: boolean + name: + description: Name is the name of the Helm + parameter + type: string + value: + description: Value is the value for the + Helm parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials + to all domains (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release + name to use. If omitted it will use the application + name + type: string + skipCrds: + description: SkipCrds skips custom resource + definition installation step (Helm's --skip-crds) + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value + files to use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to + be passed to helm template, typically defined + as a block + type: string + version: + description: Version is the Helm version to + use for templating ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific + options + properties: + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of + additional annotations to add to rendered + manifests + type: object + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional + labels to add to rendered manifests + type: object + forceCommonAnnotations: + description: ForceCommonAnnotations specifies + whether to force applying common annotations + to resources for Kustomize apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether + to force applying common labels to resources + for Kustomize apps + type: boolean + images: + description: Images is a list of Kustomize image + override specifications + items: + description: KustomizeImage represents a Kustomize + image definition in the format [old_image_name=]: + type: string + type: array + namePrefix: + description: NamePrefix is a prefix appended + to resources for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended + to resources for Kustomize apps + type: string + version: + description: Version controls which version + of Kustomize to use for rendering manifests + type: string + type: object + path: + description: Path is a directory path within the + Git repository, and is only valid for applications + sourced from Git. + type: string + plugin: + description: Plugin holds config management plugin + specific options + properties: + env: + description: Env is a list of environment variable + entries + items: + description: EnvEntry represents an entry + in the application's environment + properties: + name: + description: Name is the name of the variable, + usually expressed in uppercase + type: string + value: + description: Value is the value of the + variable + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + description: Array is the value of an + array type parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map + type parameter. + type: object + name: + description: Name is the name identifying + a parameter. + type: string + string: + description: String_ is the value of a + string type parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source + within sources field. This field will not be used + if used with a `source` tag. + type: string + repoURL: + description: RepoURL is the URL to the repository + (Git or Helm) that contains the application manifests + type: string + targetRevision: + description: TargetRevision defines the revision + of the source to sync the application to. In case + of Git, this can be commit, tag, or branch. If + omitted, will equal to HEAD. In case of Helm, + this is a semver tag for the Chart's version. + type: string + required: + - repoURL + type: object + type: array syncOptions: description: SyncOptions provide per-sync sync-options, e.g. Validate=false @@ -1662,6 +2778,12 @@ spec: description: Revision holds the revision this sync operation was performed to type: string + revisions: + description: Revisions holds the revision this sync operation + was performed for respective indexed source in sources field + items: + type: string + type: array source: description: Source records the application source information of the sync, used for comparing auto-sync @@ -1908,6 +3030,11 @@ spec: type: object type: array type: object + ref: + description: Ref is reference to another source within + sources field. This field will not be used if used with + a `source` tag. + type: string repoURL: description: RepoURL is the URL to the repository (Git or Helm) that contains the application manifests @@ -1922,6 +3049,284 @@ spec: required: - repoURL type: object + sources: + description: Source records the application source information + of the sync, used for comparing auto-sync + items: + description: ApplicationSource contains all required information + about the source of an application + properties: + chart: + description: Chart is a Helm chart name, and must be + specified for applications sourced from a Helm repo. + type: string + directory: + description: Directory holds path/directory specific + options + properties: + exclude: + description: Exclude contains a glob pattern to + match paths against that should be explicitly + excluded from being used during manifest generation + type: string + include: + description: Include contains a glob pattern to + match paths against that should be explicitly + included during manifest generation + type: string + jsonnet: + description: Jsonnet holds options specific to Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet External + Variables + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest + generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level + Arguments + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest + generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan a + directory recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options + properties: + fileParameters: + description: FileParameters are file parameters + to the helm template + items: + description: HelmFileParameter is a file parameter + that's passed to helm template during manifest + generation + properties: + name: + description: Name is the name of the Helm + parameter + type: string + path: + description: Path is the path to the file + containing the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents helm + template from failing when valueFiles do not exist + locally by not appending them to helm template + --values + type: boolean + parameters: + description: Parameters is a list of Helm parameters + which are passed to the helm template command + upon manifest generation + items: + description: HelmParameter is a parameter that's + passed to helm template during manifest generation + properties: + forceString: + description: ForceString determines whether + to tell Helm to interpret booleans and numbers + as strings + type: boolean + name: + description: Name is the name of the Helm + parameter + type: string + value: + description: Value is the value for the Helm + parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials to + all domains (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release name + to use. If omitted it will use the application + name + type: string + skipCrds: + description: SkipCrds skips custom resource definition + installation step (Helm's --skip-crds) + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value + files to use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to be + passed to helm template, typically defined as + a block + type: string + version: + description: Version is the Helm version to use + for templating ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific options + properties: + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of additional + annotations to add to rendered manifests + type: object + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional + labels to add to rendered manifests + type: object + forceCommonAnnotations: + description: ForceCommonAnnotations specifies whether + to force applying common annotations to resources + for Kustomize apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether + to force applying common labels to resources for + Kustomize apps + type: boolean + images: + description: Images is a list of Kustomize image + override specifications + items: + description: KustomizeImage represents a Kustomize + image definition in the format [old_image_name=]: + type: string + type: array + namePrefix: + description: NamePrefix is a prefix appended to + resources for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended to + resources for Kustomize apps + type: string + version: + description: Version controls which version of Kustomize + to use for rendering manifests + type: string + type: object + path: + description: Path is a directory path within the Git + repository, and is only valid for applications sourced + from Git. + type: string + plugin: + description: Plugin holds config management plugin specific + options + properties: + env: + description: Env is a list of environment variable + entries + items: + description: EnvEntry represents an entry in the + application's environment + properties: + name: + description: Name is the name of the variable, + usually expressed in uppercase + type: string + value: + description: Value is the value of the variable + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + description: Array is the value of an array + type parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map type + parameter. + type: object + name: + description: Name is the name identifying + a parameter. + type: string + string: + description: String_ is the value of a string + type parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source within + sources field. This field will not be used if used + with a `source` tag. + type: string + repoURL: + description: RepoURL is the URL to the repository (Git + or Helm) that contains the application manifests + type: string + targetRevision: + description: TargetRevision defines the revision of + the source to sync the application to. In case of + Git, this can be commit, tag, or branch. If omitted, + will equal to HEAD. In case of Helm, this is a semver + tag for the Chart's version. + type: string + required: + - repoURL + type: object + type: array required: - revision type: object @@ -1985,6 +3390,14 @@ spec: sourceType: description: SourceType specifies the type of this application type: string + sourceTypes: + description: SourceTypes specifies the type of the sources included + in the application + items: + description: ApplicationSourceType specifies the type of the application's + source + type: string + type: array summary: description: Summary contains a list of URLs and container images used by this application @@ -2274,6 +3687,11 @@ spec: type: object type: array type: object + ref: + description: Ref is reference to another source within + sources field. This field will not be used if used with + a `source` tag. + type: string repoURL: description: RepoURL is the URL to the repository (Git or Helm) that contains the application manifests @@ -2288,14 +3706,297 @@ spec: required: - repoURL type: object + sources: + description: Sources is a reference to the application's multiple + sources used for comparison + items: + description: ApplicationSource contains all required information + about the source of an application + properties: + chart: + description: Chart is a Helm chart name, and must be + specified for applications sourced from a Helm repo. + type: string + directory: + description: Directory holds path/directory specific + options + properties: + exclude: + description: Exclude contains a glob pattern to + match paths against that should be explicitly + excluded from being used during manifest generation + type: string + include: + description: Include contains a glob pattern to + match paths against that should be explicitly + included during manifest generation + type: string + jsonnet: + description: Jsonnet holds options specific to Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet External + Variables + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest + generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level + Arguments + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest + generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan a + directory recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options + properties: + fileParameters: + description: FileParameters are file parameters + to the helm template + items: + description: HelmFileParameter is a file parameter + that's passed to helm template during manifest + generation + properties: + name: + description: Name is the name of the Helm + parameter + type: string + path: + description: Path is the path to the file + containing the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents helm + template from failing when valueFiles do not exist + locally by not appending them to helm template + --values + type: boolean + parameters: + description: Parameters is a list of Helm parameters + which are passed to the helm template command + upon manifest generation + items: + description: HelmParameter is a parameter that's + passed to helm template during manifest generation + properties: + forceString: + description: ForceString determines whether + to tell Helm to interpret booleans and numbers + as strings + type: boolean + name: + description: Name is the name of the Helm + parameter + type: string + value: + description: Value is the value for the Helm + parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials to + all domains (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release name + to use. If omitted it will use the application + name + type: string + skipCrds: + description: SkipCrds skips custom resource definition + installation step (Helm's --skip-crds) + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value + files to use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to be + passed to helm template, typically defined as + a block + type: string + version: + description: Version is the Helm version to use + for templating ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific options + properties: + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of additional + annotations to add to rendered manifests + type: object + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional + labels to add to rendered manifests + type: object + forceCommonAnnotations: + description: ForceCommonAnnotations specifies whether + to force applying common annotations to resources + for Kustomize apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether + to force applying common labels to resources for + Kustomize apps + type: boolean + images: + description: Images is a list of Kustomize image + override specifications + items: + description: KustomizeImage represents a Kustomize + image definition in the format [old_image_name=]: + type: string + type: array + namePrefix: + description: NamePrefix is a prefix appended to + resources for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended to + resources for Kustomize apps + type: string + version: + description: Version controls which version of Kustomize + to use for rendering manifests + type: string + type: object + path: + description: Path is a directory path within the Git + repository, and is only valid for applications sourced + from Git. + type: string + plugin: + description: Plugin holds config management plugin specific + options + properties: + env: + description: Env is a list of environment variable + entries + items: + description: EnvEntry represents an entry in the + application's environment + properties: + name: + description: Name is the name of the variable, + usually expressed in uppercase + type: string + value: + description: Value is the value of the variable + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + description: Array is the value of an array + type parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map type + parameter. + type: object + name: + description: Name is the name identifying + a parameter. + type: string + string: + description: String_ is the value of a string + type parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source within + sources field. This field will not be used if used + with a `source` tag. + type: string + repoURL: + description: RepoURL is the URL to the repository (Git + or Helm) that contains the application manifests + type: string + targetRevision: + description: TargetRevision defines the revision of + the source to sync the application to. In case of + Git, this can be commit, tag, or branch. If omitted, + will equal to HEAD. In case of Helm, this is a semver + tag for the Chart's version. + type: string + required: + - repoURL + type: object + type: array required: - destination - - source type: object revision: description: Revision contains information about the revision the comparison has been performed to type: string + revisions: + description: Revisions contains information about the revisions + of multiple sources the comparison has been performed to + items: + type: string + type: array status: description: Status is the sync state of the comparison type: string @@ -2601,6 +4302,8 @@ spec: type: object type: array type: object + ref: + type: string repoURL: type: string targetRevision: @@ -2608,6 +4311,165 @@ spec: required: - repoURL type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array syncPolicy: properties: automated: @@ -2654,7 +4516,6 @@ spec: required: - destination - project - - source type: object required: - metadata @@ -2916,6 +4777,8 @@ spec: type: object type: array type: object + ref: + type: string repoURL: type: string targetRevision: @@ -2923,6 +4786,165 @@ spec: required: - repoURL type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array syncPolicy: properties: automated: @@ -2969,7 +4991,6 @@ spec: required: - destination - project - - source type: object required: - metadata @@ -3214,34 +5235,195 @@ spec: - name - value type: object - type: array - name: - type: string - parameters: - items: - properties: - array: - items: + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: type: string - type: array - map: - additionalProperties: + value: type: string - type: object - name: - type: string - string: - type: string - type: object - type: array - type: object - repoURL: - type: string - targetRevision: - type: string - required: - - repoURL - type: object + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array syncPolicy: properties: automated: @@ -3288,7 +5470,6 @@ spec: required: - destination - project - - source type: object required: - metadata @@ -3529,6 +5710,8 @@ spec: type: object type: array type: object + ref: + type: string repoURL: type: string targetRevision: @@ -3536,6 +5719,165 @@ spec: required: - repoURL type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array syncPolicy: properties: automated: @@ -3582,7 +5924,6 @@ spec: required: - destination - project - - source type: object required: - metadata @@ -3852,6 +6193,8 @@ spec: type: object type: array type: object + ref: + type: string repoURL: type: string targetRevision: @@ -3859,6 +6202,165 @@ spec: required: - repoURL type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array syncPolicy: properties: automated: @@ -3905,7 +6407,6 @@ spec: required: - destination - project - - source type: object required: - metadata @@ -4155,25 +6656,186 @@ spec: array: items: type: string - type: array - map: - additionalProperties: + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: type: string - type: object - name: - type: string - string: - type: string - type: object - type: array - type: object - repoURL: - type: string - targetRevision: - type: string - required: - - repoURL - type: object + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array syncPolicy: properties: automated: @@ -4220,7 +6882,6 @@ spec: required: - destination - project - - source type: object required: - metadata @@ -4486,6 +7147,8 @@ spec: type: object type: array type: object + ref: + type: string repoURL: type: string targetRevision: @@ -4493,6 +7156,165 @@ spec: required: - repoURL type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array syncPolicy: properties: automated: @@ -4539,7 +7361,6 @@ spec: required: - destination - project - - source type: object required: - metadata @@ -4780,6 +7601,8 @@ spec: type: object type: array type: object + ref: + type: string repoURL: type: string targetRevision: @@ -4787,6 +7610,165 @@ spec: required: - repoURL type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array syncPolicy: properties: automated: @@ -4833,7 +7815,6 @@ spec: required: - destination - project - - source type: object required: - metadata @@ -5191,6 +8172,8 @@ spec: type: object type: array type: object + ref: + type: string repoURL: type: string targetRevision: @@ -5198,6 +8181,165 @@ spec: required: - repoURL type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array syncPolicy: properties: automated: @@ -5244,7 +8386,6 @@ spec: required: - destination - project - - source type: object required: - metadata @@ -5649,6 +8790,8 @@ spec: type: object type: array type: object + ref: + type: string repoURL: type: string targetRevision: @@ -5656,6 +8799,165 @@ spec: required: - repoURL type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array syncPolicy: properties: automated: @@ -5702,7 +9004,6 @@ spec: required: - destination - project - - source type: object required: - metadata @@ -5946,25 +9247,186 @@ spec: array: items: type: string - type: array - map: - additionalProperties: + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: type: string - type: object - name: - type: string - string: - type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string type: object - type: array - type: object - repoURL: - type: string - targetRevision: - type: string - required: - - repoURL - type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array syncPolicy: properties: automated: @@ -6011,7 +9473,6 @@ spec: required: - destination - project - - source type: object required: - metadata @@ -6281,6 +9742,8 @@ spec: type: object type: array type: object + ref: + type: string repoURL: type: string targetRevision: @@ -6288,6 +9751,165 @@ spec: required: - repoURL type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array syncPolicy: properties: automated: @@ -6334,7 +9956,6 @@ spec: required: - destination - project - - source type: object required: - metadata @@ -6596,6 +10217,8 @@ spec: type: object type: array type: object + ref: + type: string repoURL: type: string targetRevision: @@ -6603,6 +10226,165 @@ spec: required: - repoURL type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array syncPolicy: properties: automated: @@ -6649,7 +10431,6 @@ spec: required: - destination - project - - source type: object required: - metadata @@ -6915,6 +10696,8 @@ spec: type: object type: array type: object + ref: + type: string repoURL: type: string targetRevision: @@ -6922,6 +10705,165 @@ spec: required: - repoURL type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array syncPolicy: properties: automated: @@ -6968,7 +10910,6 @@ spec: required: - destination - project - - source type: object required: - metadata @@ -7209,6 +11150,8 @@ spec: type: object type: array type: object + ref: + type: string repoURL: type: string targetRevision: @@ -7216,6 +11159,165 @@ spec: required: - repoURL type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array syncPolicy: properties: automated: @@ -7262,7 +11364,6 @@ spec: required: - destination - project - - source type: object required: - metadata @@ -7620,6 +11721,8 @@ spec: type: object type: array type: object + ref: + type: string repoURL: type: string targetRevision: @@ -7627,6 +11730,165 @@ spec: required: - repoURL type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array syncPolicy: properties: automated: @@ -7673,7 +11935,6 @@ spec: required: - destination - project - - source type: object required: - metadata @@ -8078,6 +12339,8 @@ spec: type: object type: array type: object + ref: + type: string repoURL: type: string targetRevision: @@ -8085,6 +12348,165 @@ spec: required: - repoURL type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array syncPolicy: properties: automated: @@ -8131,7 +12553,6 @@ spec: required: - destination - project - - source type: object required: - metadata @@ -8391,6 +12812,8 @@ spec: type: object type: array type: object + ref: + type: string repoURL: type: string targetRevision: @@ -8398,6 +12821,165 @@ spec: required: - repoURL type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array syncPolicy: properties: automated: @@ -8444,7 +13026,6 @@ spec: required: - destination - project - - source type: object required: - metadata @@ -8787,25 +13368,186 @@ spec: array: items: type: string - type: array - map: - additionalProperties: + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: type: string - type: object - name: - type: string - string: - type: string - type: object - type: array - type: object - repoURL: - type: string - targetRevision: - type: string - required: - - repoURL - type: object + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array syncPolicy: properties: automated: @@ -8852,7 +13594,6 @@ spec: required: - destination - project - - source type: object required: - metadata @@ -9257,6 +13998,8 @@ spec: type: object type: array type: object + ref: + type: string repoURL: type: string targetRevision: @@ -9264,6 +14007,165 @@ spec: required: - repoURL type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array syncPolicy: properties: automated: @@ -9310,7 +14212,6 @@ spec: required: - destination - project - - source type: object required: - metadata @@ -9573,6 +14474,8 @@ spec: type: object type: array type: object + ref: + type: string repoURL: type: string targetRevision: @@ -9580,6 +14483,165 @@ spec: required: - repoURL type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array syncPolicy: properties: automated: @@ -9626,7 +14688,6 @@ spec: required: - destination - project - - source type: object required: - metadata diff --git a/manifests/crds/application-crd.yaml b/manifests/crds/application-crd.yaml index 16744f696500e..d19394e84f8fd 100644 --- a/manifests/crds/application-crd.yaml +++ b/manifests/crds/application-crd.yaml @@ -143,6 +143,14 @@ spec: which to sync the application to If omitted, will use the revision specified in app spec. type: string + revisions: + description: Revisions is the list of revision (Git) or chart + version (Helm) which to sync each source in sources field for + the application to If omitted, will use the revision specified + in app spec. + items: + type: string + type: array source: description: Source overrides the source definition set in the application. This is typically set in a Rollback operation and @@ -382,6 +390,11 @@ spec: type: object type: array type: object + ref: + description: Ref is reference to another source within sources + field. This field will not be used if used with a `source` + tag. + type: string repoURL: description: RepoURL is the URL to the repository (Git or Helm) that contains the application manifests @@ -395,6 +408,271 @@ spec: required: - repoURL type: object + sources: + description: Sources overrides the source definition set in the + application. This is typically set in a Rollback operation and + is nil during a Sync operation + items: + description: ApplicationSource contains all required information + about the source of an application + properties: + chart: + description: Chart is a Helm chart name, and must be specified + for applications sourced from a Helm repo. + type: string + directory: + description: Directory holds path/directory specific options + properties: + exclude: + description: Exclude contains a glob pattern to match + paths against that should be explicitly excluded from + being used during manifest generation + type: string + include: + description: Include contains a glob pattern to match + paths against that should be explicitly included during + manifest generation + type: string + jsonnet: + description: Jsonnet holds options specific to Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet External + Variables + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level + Arguments + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan a directory + recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options + properties: + fileParameters: + description: FileParameters are file parameters to the + helm template + items: + description: HelmFileParameter is a file parameter + that's passed to helm template during manifest generation + properties: + name: + description: Name is the name of the Helm parameter + type: string + path: + description: Path is the path to the file containing + the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents helm template + from failing when valueFiles do not exist locally + by not appending them to helm template --values + type: boolean + parameters: + description: Parameters is a list of Helm parameters + which are passed to the helm template command upon + manifest generation + items: + description: HelmParameter is a parameter that's passed + to helm template during manifest generation + properties: + forceString: + description: ForceString determines whether to + tell Helm to interpret booleans and numbers + as strings + type: boolean + name: + description: Name is the name of the Helm parameter + type: string + value: + description: Value is the value for the Helm parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials to all + domains (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release name to + use. If omitted it will use the application name + type: string + skipCrds: + description: SkipCrds skips custom resource definition + installation step (Helm's --skip-crds) + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value files + to use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to be passed + to helm template, typically defined as a block + type: string + version: + description: Version is the Helm version to use for + templating ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific options + properties: + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of additional + annotations to add to rendered manifests + type: object + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional labels + to add to rendered manifests + type: object + forceCommonAnnotations: + description: ForceCommonAnnotations specifies whether + to force applying common annotations to resources + for Kustomize apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether to + force applying common labels to resources for Kustomize + apps + type: boolean + images: + description: Images is a list of Kustomize image override + specifications + items: + description: KustomizeImage represents a Kustomize + image definition in the format [old_image_name=]: + type: string + type: array + namePrefix: + description: NamePrefix is a prefix appended to resources + for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended to resources + for Kustomize apps + type: string + version: + description: Version controls which version of Kustomize + to use for rendering manifests + type: string + type: object + path: + description: Path is a directory path within the Git repository, + and is only valid for applications sourced from Git. + type: string + plugin: + description: Plugin holds config management plugin specific + options + properties: + env: + description: Env is a list of environment variable entries + items: + description: EnvEntry represents an entry in the application's + environment + properties: + name: + description: Name is the name of the variable, + usually expressed in uppercase + type: string + value: + description: Value is the value of the variable + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + description: Array is the value of an array type + parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map type parameter. + type: object + name: + description: Name is the name identifying a parameter. + type: string + string: + description: String_ is the value of a string + type parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source within sources + field. This field will not be used if used with a `source` + tag. + type: string + repoURL: + description: RepoURL is the URL to the repository (Git or + Helm) that contains the application manifests + type: string + targetRevision: + description: TargetRevision defines the revision of the + source to sync the application to. In case of Git, this + can be commit, tag, or branch. If omitted, will equal + to HEAD. In case of Helm, this is a semver tag for the + Chart's version. + type: string + required: + - repoURL + type: object + type: array syncOptions: description: SyncOptions provide per-sync sync-options, e.g. Validate=false items: @@ -733,34 +1011,296 @@ spec: description: Array is the value of an array type parameter. items: type: string - type: array - map: - additionalProperties: + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map type parameter. + type: object + name: + description: Name is the name identifying a parameter. + type: string + string: + description: String_ is the value of a string type parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source within sources + field. This field will not be used if used with a `source` tag. + type: string + repoURL: + description: RepoURL is the URL to the repository (Git or Helm) + that contains the application manifests + type: string + targetRevision: + description: TargetRevision defines the revision of the source + to sync the application to. In case of Git, this can be commit, + tag, or branch. If omitted, will equal to HEAD. In case of Helm, + this is a semver tag for the Chart's version. + type: string + required: + - repoURL + type: object + sources: + description: Sources is a reference to the location of the application's + manifests or chart + items: + description: ApplicationSource contains all required information + about the source of an application + properties: + chart: + description: Chart is a Helm chart name, and must be specified + for applications sourced from a Helm repo. + type: string + directory: + description: Directory holds path/directory specific options + properties: + exclude: + description: Exclude contains a glob pattern to match paths + against that should be explicitly excluded from being + used during manifest generation + type: string + include: + description: Include contains a glob pattern to match paths + against that should be explicitly included during manifest + generation + type: string + jsonnet: + description: Jsonnet holds options specific to Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet External Variables + items: + description: JsonnetVar represents a variable to be + passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level Arguments + items: + description: JsonnetVar represents a variable to be + passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan a directory + recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options + properties: + fileParameters: + description: FileParameters are file parameters to the helm + template + items: + description: HelmFileParameter is a file parameter that's + passed to helm template during manifest generation + properties: + name: + description: Name is the name of the Helm parameter + type: string + path: + description: Path is the path to the file containing + the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents helm template + from failing when valueFiles do not exist locally by not + appending them to helm template --values + type: boolean + parameters: + description: Parameters is a list of Helm parameters which + are passed to the helm template command upon manifest + generation + items: + description: HelmParameter is a parameter that's passed + to helm template during manifest generation + properties: + forceString: + description: ForceString determines whether to tell + Helm to interpret booleans and numbers as strings + type: boolean + name: + description: Name is the name of the Helm parameter type: string - description: Map is the value of a map type parameter. - type: object - name: - description: Name is the name identifying a parameter. - type: string - string: - description: String_ is the value of a string type parameter. - type: string + value: + description: Value is the value for the Helm parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials to all domains + (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release name to use. + If omitted it will use the application name + type: string + skipCrds: + description: SkipCrds skips custom resource definition installation + step (Helm's --skip-crds) + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value files to + use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to be passed to + helm template, typically defined as a block + type: string + version: + description: Version is the Helm version to use for templating + ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific options + properties: + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of additional annotations + to add to rendered manifests type: object - type: array - type: object - repoURL: - description: RepoURL is the URL to the repository (Git or Helm) - that contains the application manifests - type: string - targetRevision: - description: TargetRevision defines the revision of the source - to sync the application to. In case of Git, this can be commit, - tag, or branch. If omitted, will equal to HEAD. In case of Helm, - this is a semver tag for the Chart's version. - type: string - required: - - repoURL - type: object + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional labels + to add to rendered manifests + type: object + forceCommonAnnotations: + description: ForceCommonAnnotations specifies whether to + force applying common annotations to resources for Kustomize + apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether to force + applying common labels to resources for Kustomize apps + type: boolean + images: + description: Images is a list of Kustomize image override + specifications + items: + description: KustomizeImage represents a Kustomize image + definition in the format [old_image_name=]: + type: string + type: array + namePrefix: + description: NamePrefix is a prefix appended to resources + for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended to resources + for Kustomize apps + type: string + version: + description: Version controls which version of Kustomize + to use for rendering manifests + type: string + type: object + path: + description: Path is a directory path within the Git repository, + and is only valid for applications sourced from Git. + type: string + plugin: + description: Plugin holds config management plugin specific + options + properties: + env: + description: Env is a list of environment variable entries + items: + description: EnvEntry represents an entry in the application's + environment + properties: + name: + description: Name is the name of the variable, usually + expressed in uppercase + type: string + value: + description: Value is the value of the variable + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + description: Array is the value of an array type parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map type parameter. + type: object + name: + description: Name is the name identifying a parameter. + type: string + string: + description: String_ is the value of a string type + parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source within sources + field. This field will not be used if used with a `source` + tag. + type: string + repoURL: + description: RepoURL is the URL to the repository (Git or Helm) + that contains the application manifests + type: string + targetRevision: + description: TargetRevision defines the revision of the source + to sync the application to. In case of Git, this can be commit, + tag, or branch. If omitted, will equal to HEAD. In case of + Helm, this is a semver tag for the Chart's version. + type: string + required: + - repoURL + type: object + type: array syncPolicy: description: SyncPolicy controls when and how a sync will be performed properties: @@ -833,7 +1373,6 @@ spec: required: - destination - project - - source type: object status: description: ApplicationStatus contains status information for the application @@ -899,6 +1438,12 @@ spec: description: Revision holds the revision the sync was performed against type: string + revisions: + description: Revisions holds the revision of each source in + sources field the sync was performed against + items: + type: string + type: array source: description: Source is a reference to the application source used for the sync operation @@ -1113,51 +1658,324 @@ spec: - name - value type: object - type: array - name: - type: string - parameters: - items: - properties: - array: - description: Array is the value of an array type - parameter. - items: + type: array + name: + type: string + parameters: + items: + properties: + array: + description: Array is the value of an array type + parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map type parameter. + type: object + name: + description: Name is the name identifying a parameter. + type: string + string: + description: String_ is the value of a string + type parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source within sources + field. This field will not be used if used with a `source` + tag. + type: string + repoURL: + description: RepoURL is the URL to the repository (Git or + Helm) that contains the application manifests + type: string + targetRevision: + description: TargetRevision defines the revision of the + source to sync the application to. In case of Git, this + can be commit, tag, or branch. If omitted, will equal + to HEAD. In case of Helm, this is a semver tag for the + Chart's version. + type: string + required: + - repoURL + type: object + sources: + description: Sources is a reference to the application sources + used for the sync operation + items: + description: ApplicationSource contains all required information + about the source of an application + properties: + chart: + description: Chart is a Helm chart name, and must be specified + for applications sourced from a Helm repo. + type: string + directory: + description: Directory holds path/directory specific options + properties: + exclude: + description: Exclude contains a glob pattern to match + paths against that should be explicitly excluded + from being used during manifest generation + type: string + include: + description: Include contains a glob pattern to match + paths against that should be explicitly included + during manifest generation + type: string + jsonnet: + description: Jsonnet holds options specific to Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet External + Variables + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level + Arguments + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan a directory + recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options + properties: + fileParameters: + description: FileParameters are file parameters to + the helm template + items: + description: HelmFileParameter is a file parameter + that's passed to helm template during manifest + generation + properties: + name: + description: Name is the name of the Helm parameter + type: string + path: + description: Path is the path to the file containing + the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents helm + template from failing when valueFiles do not exist + locally by not appending them to helm template --values + type: boolean + parameters: + description: Parameters is a list of Helm parameters + which are passed to the helm template command upon + manifest generation + items: + description: HelmParameter is a parameter that's + passed to helm template during manifest generation + properties: + forceString: + description: ForceString determines whether + to tell Helm to interpret booleans and numbers + as strings + type: boolean + name: + description: Name is the name of the Helm parameter + type: string + value: + description: Value is the value for the Helm + parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials to all + domains (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release name + to use. If omitted it will use the application name + type: string + skipCrds: + description: SkipCrds skips custom resource definition + installation step (Helm's --skip-crds) + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value files + to use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to be passed + to helm template, typically defined as a block + type: string + version: + description: Version is the Helm version to use for + templating ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific options + properties: + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of additional + annotations to add to rendered manifests + type: object + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional + labels to add to rendered manifests + type: object + forceCommonAnnotations: + description: ForceCommonAnnotations specifies whether + to force applying common annotations to resources + for Kustomize apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether to + force applying common labels to resources for Kustomize + apps + type: boolean + images: + description: Images is a list of Kustomize image override + specifications + items: + description: KustomizeImage represents a Kustomize + image definition in the format [old_image_name=]: + type: string + type: array + namePrefix: + description: NamePrefix is a prefix appended to resources + for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended to resources + for Kustomize apps + type: string + version: + description: Version controls which version of Kustomize + to use for rendering manifests + type: string + type: object + path: + description: Path is a directory path within the Git repository, + and is only valid for applications sourced from Git. + type: string + plugin: + description: Plugin holds config management plugin specific + options + properties: + env: + description: Env is a list of environment variable + entries + items: + description: EnvEntry represents an entry in the + application's environment + properties: + name: + description: Name is the name of the variable, + usually expressed in uppercase type: string - type: array - map: - additionalProperties: + value: + description: Value is the value of the variable type: string - description: Map is the value of a map type parameter. - type: object - name: - description: Name is the name identifying a parameter. - type: string - string: - description: String_ is the value of a string - type parameter. - type: string - type: object - type: array - type: object - repoURL: - description: RepoURL is the URL to the repository (Git or - Helm) that contains the application manifests - type: string - targetRevision: - description: TargetRevision defines the revision of the - source to sync the application to. In case of Git, this - can be commit, tag, or branch. If omitted, will equal - to HEAD. In case of Helm, this is a semver tag for the - Chart's version. - type: string - required: - - repoURL - type: object + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + description: Array is the value of an array + type parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map type + parameter. + type: object + name: + description: Name is the name identifying a + parameter. + type: string + string: + description: String_ is the value of a string + type parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source within + sources field. This field will not be used if used with + a `source` tag. + type: string + repoURL: + description: RepoURL is the URL to the repository (Git + or Helm) that contains the application manifests + type: string + targetRevision: + description: TargetRevision defines the revision of the + source to sync the application to. In case of Git, this + can be commit, tag, or branch. If omitted, will equal + to HEAD. In case of Helm, this is a semver tag for the + Chart's version. + type: string + required: + - repoURL + type: object + type: array required: - deployedAt - id - - revision type: object type: array observedAt: @@ -1280,6 +2098,14 @@ spec: (Helm) which to sync the application to If omitted, will use the revision specified in app spec. type: string + revisions: + description: Revisions is the list of revision (Git) or + chart version (Helm) which to sync each source in sources + field for the application to If omitted, will use the + revision specified in app spec. + items: + type: string + type: array source: description: Source overrides the source definition set in the application. This is typically set in a Rollback @@ -1520,38 +2346,328 @@ spec: type parameter. items: type: string - type: array - map: - additionalProperties: + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map type + parameter. + type: object + name: + description: Name is the name identifying + a parameter. + type: string + string: + description: String_ is the value of a string + type parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source within + sources field. This field will not be used if used + with a `source` tag. + type: string + repoURL: + description: RepoURL is the URL to the repository + (Git or Helm) that contains the application manifests + type: string + targetRevision: + description: TargetRevision defines the revision of + the source to sync the application to. In case of + Git, this can be commit, tag, or branch. If omitted, + will equal to HEAD. In case of Helm, this is a semver + tag for the Chart's version. + type: string + required: + - repoURL + type: object + sources: + description: Sources overrides the source definition set + in the application. This is typically set in a Rollback + operation and is nil during a Sync operation + items: + description: ApplicationSource contains all required + information about the source of an application + properties: + chart: + description: Chart is a Helm chart name, and must + be specified for applications sourced from a Helm + repo. + type: string + directory: + description: Directory holds path/directory specific + options + properties: + exclude: + description: Exclude contains a glob pattern + to match paths against that should be explicitly + excluded from being used during manifest generation + type: string + include: + description: Include contains a glob pattern + to match paths against that should be explicitly + included during manifest generation + type: string + jsonnet: + description: Jsonnet holds options specific + to Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet + External Variables + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest + generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level + Arguments + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest + generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan + a directory recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options + properties: + fileParameters: + description: FileParameters are file parameters + to the helm template + items: + description: HelmFileParameter is a file parameter + that's passed to helm template during manifest + generation + properties: + name: + description: Name is the name of the Helm + parameter + type: string + path: + description: Path is the path to the file + containing the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents + helm template from failing when valueFiles + do not exist locally by not appending them + to helm template --values + type: boolean + parameters: + description: Parameters is a list of Helm parameters + which are passed to the helm template command + upon manifest generation + items: + description: HelmParameter is a parameter + that's passed to helm template during manifest + generation + properties: + forceString: + description: ForceString determines whether + to tell Helm to interpret booleans and + numbers as strings + type: boolean + name: + description: Name is the name of the Helm + parameter + type: string + value: + description: Value is the value for the + Helm parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials + to all domains (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release + name to use. If omitted it will use the application + name + type: string + skipCrds: + description: SkipCrds skips custom resource + definition installation step (Helm's --skip-crds) + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value + files to use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to + be passed to helm template, typically defined + as a block + type: string + version: + description: Version is the Helm version to + use for templating ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific + options + properties: + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of + additional annotations to add to rendered + manifests + type: object + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional + labels to add to rendered manifests + type: object + forceCommonAnnotations: + description: ForceCommonAnnotations specifies + whether to force applying common annotations + to resources for Kustomize apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether + to force applying common labels to resources + for Kustomize apps + type: boolean + images: + description: Images is a list of Kustomize image + override specifications + items: + description: KustomizeImage represents a Kustomize + image definition in the format [old_image_name=]: + type: string + type: array + namePrefix: + description: NamePrefix is a prefix appended + to resources for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended + to resources for Kustomize apps + type: string + version: + description: Version controls which version + of Kustomize to use for rendering manifests + type: string + type: object + path: + description: Path is a directory path within the + Git repository, and is only valid for applications + sourced from Git. + type: string + plugin: + description: Plugin holds config management plugin + specific options + properties: + env: + description: Env is a list of environment variable + entries + items: + description: EnvEntry represents an entry + in the application's environment + properties: + name: + description: Name is the name of the variable, + usually expressed in uppercase + type: string + value: + description: Value is the value of the + variable type: string - description: Map is the value of a map type - parameter. - type: object - name: - description: Name is the name identifying - a parameter. - type: string - string: - description: String_ is the value of a string - type parameter. - type: string - type: object - type: array - type: object - repoURL: - description: RepoURL is the URL to the repository - (Git or Helm) that contains the application manifests - type: string - targetRevision: - description: TargetRevision defines the revision of - the source to sync the application to. In case of - Git, this can be commit, tag, or branch. If omitted, - will equal to HEAD. In case of Helm, this is a semver - tag for the Chart's version. - type: string - required: - - repoURL - type: object + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + description: Array is the value of an + array type parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map + type parameter. + type: object + name: + description: Name is the name identifying + a parameter. + type: string + string: + description: String_ is the value of a + string type parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source + within sources field. This field will not be used + if used with a `source` tag. + type: string + repoURL: + description: RepoURL is the URL to the repository + (Git or Helm) that contains the application manifests + type: string + targetRevision: + description: TargetRevision defines the revision + of the source to sync the application to. In case + of Git, this can be commit, tag, or branch. If + omitted, will equal to HEAD. In case of Helm, + this is a semver tag for the Chart's version. + type: string + required: + - repoURL + type: object + type: array syncOptions: description: SyncOptions provide per-sync sync-options, e.g. Validate=false @@ -1661,6 +2777,12 @@ spec: description: Revision holds the revision this sync operation was performed to type: string + revisions: + description: Revisions holds the revision this sync operation + was performed for respective indexed source in sources field + items: + type: string + type: array source: description: Source records the application source information of the sync, used for comparing auto-sync @@ -1907,6 +3029,11 @@ spec: type: object type: array type: object + ref: + description: Ref is reference to another source within + sources field. This field will not be used if used with + a `source` tag. + type: string repoURL: description: RepoURL is the URL to the repository (Git or Helm) that contains the application manifests @@ -1921,6 +3048,284 @@ spec: required: - repoURL type: object + sources: + description: Source records the application source information + of the sync, used for comparing auto-sync + items: + description: ApplicationSource contains all required information + about the source of an application + properties: + chart: + description: Chart is a Helm chart name, and must be + specified for applications sourced from a Helm repo. + type: string + directory: + description: Directory holds path/directory specific + options + properties: + exclude: + description: Exclude contains a glob pattern to + match paths against that should be explicitly + excluded from being used during manifest generation + type: string + include: + description: Include contains a glob pattern to + match paths against that should be explicitly + included during manifest generation + type: string + jsonnet: + description: Jsonnet holds options specific to Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet External + Variables + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest + generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level + Arguments + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest + generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan a + directory recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options + properties: + fileParameters: + description: FileParameters are file parameters + to the helm template + items: + description: HelmFileParameter is a file parameter + that's passed to helm template during manifest + generation + properties: + name: + description: Name is the name of the Helm + parameter + type: string + path: + description: Path is the path to the file + containing the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents helm + template from failing when valueFiles do not exist + locally by not appending them to helm template + --values + type: boolean + parameters: + description: Parameters is a list of Helm parameters + which are passed to the helm template command + upon manifest generation + items: + description: HelmParameter is a parameter that's + passed to helm template during manifest generation + properties: + forceString: + description: ForceString determines whether + to tell Helm to interpret booleans and numbers + as strings + type: boolean + name: + description: Name is the name of the Helm + parameter + type: string + value: + description: Value is the value for the Helm + parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials to + all domains (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release name + to use. If omitted it will use the application + name + type: string + skipCrds: + description: SkipCrds skips custom resource definition + installation step (Helm's --skip-crds) + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value + files to use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to be + passed to helm template, typically defined as + a block + type: string + version: + description: Version is the Helm version to use + for templating ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific options + properties: + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of additional + annotations to add to rendered manifests + type: object + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional + labels to add to rendered manifests + type: object + forceCommonAnnotations: + description: ForceCommonAnnotations specifies whether + to force applying common annotations to resources + for Kustomize apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether + to force applying common labels to resources for + Kustomize apps + type: boolean + images: + description: Images is a list of Kustomize image + override specifications + items: + description: KustomizeImage represents a Kustomize + image definition in the format [old_image_name=]: + type: string + type: array + namePrefix: + description: NamePrefix is a prefix appended to + resources for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended to + resources for Kustomize apps + type: string + version: + description: Version controls which version of Kustomize + to use for rendering manifests + type: string + type: object + path: + description: Path is a directory path within the Git + repository, and is only valid for applications sourced + from Git. + type: string + plugin: + description: Plugin holds config management plugin specific + options + properties: + env: + description: Env is a list of environment variable + entries + items: + description: EnvEntry represents an entry in the + application's environment + properties: + name: + description: Name is the name of the variable, + usually expressed in uppercase + type: string + value: + description: Value is the value of the variable + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + description: Array is the value of an array + type parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map type + parameter. + type: object + name: + description: Name is the name identifying + a parameter. + type: string + string: + description: String_ is the value of a string + type parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source within + sources field. This field will not be used if used + with a `source` tag. + type: string + repoURL: + description: RepoURL is the URL to the repository (Git + or Helm) that contains the application manifests + type: string + targetRevision: + description: TargetRevision defines the revision of + the source to sync the application to. In case of + Git, this can be commit, tag, or branch. If omitted, + will equal to HEAD. In case of Helm, this is a semver + tag for the Chart's version. + type: string + required: + - repoURL + type: object + type: array required: - revision type: object @@ -1984,6 +3389,14 @@ spec: sourceType: description: SourceType specifies the type of this application type: string + sourceTypes: + description: SourceTypes specifies the type of the sources included + in the application + items: + description: ApplicationSourceType specifies the type of the application's + source + type: string + type: array summary: description: Summary contains a list of URLs and container images used by this application @@ -2273,6 +3686,11 @@ spec: type: object type: array type: object + ref: + description: Ref is reference to another source within + sources field. This field will not be used if used with + a `source` tag. + type: string repoURL: description: RepoURL is the URL to the repository (Git or Helm) that contains the application manifests @@ -2287,14 +3705,297 @@ spec: required: - repoURL type: object + sources: + description: Sources is a reference to the application's multiple + sources used for comparison + items: + description: ApplicationSource contains all required information + about the source of an application + properties: + chart: + description: Chart is a Helm chart name, and must be + specified for applications sourced from a Helm repo. + type: string + directory: + description: Directory holds path/directory specific + options + properties: + exclude: + description: Exclude contains a glob pattern to + match paths against that should be explicitly + excluded from being used during manifest generation + type: string + include: + description: Include contains a glob pattern to + match paths against that should be explicitly + included during manifest generation + type: string + jsonnet: + description: Jsonnet holds options specific to Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet External + Variables + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest + generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level + Arguments + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest + generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan a + directory recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options + properties: + fileParameters: + description: FileParameters are file parameters + to the helm template + items: + description: HelmFileParameter is a file parameter + that's passed to helm template during manifest + generation + properties: + name: + description: Name is the name of the Helm + parameter + type: string + path: + description: Path is the path to the file + containing the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents helm + template from failing when valueFiles do not exist + locally by not appending them to helm template + --values + type: boolean + parameters: + description: Parameters is a list of Helm parameters + which are passed to the helm template command + upon manifest generation + items: + description: HelmParameter is a parameter that's + passed to helm template during manifest generation + properties: + forceString: + description: ForceString determines whether + to tell Helm to interpret booleans and numbers + as strings + type: boolean + name: + description: Name is the name of the Helm + parameter + type: string + value: + description: Value is the value for the Helm + parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials to + all domains (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release name + to use. If omitted it will use the application + name + type: string + skipCrds: + description: SkipCrds skips custom resource definition + installation step (Helm's --skip-crds) + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value + files to use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to be + passed to helm template, typically defined as + a block + type: string + version: + description: Version is the Helm version to use + for templating ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific options + properties: + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of additional + annotations to add to rendered manifests + type: object + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional + labels to add to rendered manifests + type: object + forceCommonAnnotations: + description: ForceCommonAnnotations specifies whether + to force applying common annotations to resources + for Kustomize apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether + to force applying common labels to resources for + Kustomize apps + type: boolean + images: + description: Images is a list of Kustomize image + override specifications + items: + description: KustomizeImage represents a Kustomize + image definition in the format [old_image_name=]: + type: string + type: array + namePrefix: + description: NamePrefix is a prefix appended to + resources for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended to + resources for Kustomize apps + type: string + version: + description: Version controls which version of Kustomize + to use for rendering manifests + type: string + type: object + path: + description: Path is a directory path within the Git + repository, and is only valid for applications sourced + from Git. + type: string + plugin: + description: Plugin holds config management plugin specific + options + properties: + env: + description: Env is a list of environment variable + entries + items: + description: EnvEntry represents an entry in the + application's environment + properties: + name: + description: Name is the name of the variable, + usually expressed in uppercase + type: string + value: + description: Value is the value of the variable + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + description: Array is the value of an array + type parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map type + parameter. + type: object + name: + description: Name is the name identifying + a parameter. + type: string + string: + description: String_ is the value of a string + type parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source within + sources field. This field will not be used if used + with a `source` tag. + type: string + repoURL: + description: RepoURL is the URL to the repository (Git + or Helm) that contains the application manifests + type: string + targetRevision: + description: TargetRevision defines the revision of + the source to sync the application to. In case of + Git, this can be commit, tag, or branch. If omitted, + will equal to HEAD. In case of Helm, this is a semver + tag for the Chart's version. + type: string + required: + - repoURL + type: object + type: array required: - destination - - source type: object revision: description: Revision contains information about the revision the comparison has been performed to type: string + revisions: + description: Revisions contains information about the revisions + of multiple sources the comparison has been performed to + items: + type: string + type: array status: description: Status is the sync state of the comparison type: string diff --git a/manifests/crds/applicationset-crd.yaml b/manifests/crds/applicationset-crd.yaml index fa795e6095cce..19a23e64a10aa 100644 --- a/manifests/crds/applicationset-crd.yaml +++ b/manifests/crds/applicationset-crd.yaml @@ -288,6 +288,8 @@ spec: type: object type: array type: object + ref: + type: string repoURL: type: string targetRevision: @@ -295,6 +297,165 @@ spec: required: - repoURL type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array syncPolicy: properties: automated: @@ -341,7 +502,6 @@ spec: required: - destination - project - - source type: object required: - metadata @@ -603,6 +763,8 @@ spec: type: object type: array type: object + ref: + type: string repoURL: type: string targetRevision: @@ -610,6 +772,165 @@ spec: required: - repoURL type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array syncPolicy: properties: automated: @@ -656,7 +977,6 @@ spec: required: - destination - project - - source type: object required: - metadata @@ -922,6 +1242,8 @@ spec: type: object type: array type: object + ref: + type: string repoURL: type: string targetRevision: @@ -929,6 +1251,165 @@ spec: required: - repoURL type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array syncPolicy: properties: automated: @@ -975,7 +1456,6 @@ spec: required: - destination - project - - source type: object required: - metadata @@ -1216,6 +1696,8 @@ spec: type: object type: array type: object + ref: + type: string repoURL: type: string targetRevision: @@ -1223,6 +1705,165 @@ spec: required: - repoURL type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array syncPolicy: properties: automated: @@ -1269,7 +1910,6 @@ spec: required: - destination - project - - source type: object required: - metadata @@ -1539,6 +2179,8 @@ spec: type: object type: array type: object + ref: + type: string repoURL: type: string targetRevision: @@ -1546,6 +2188,165 @@ spec: required: - repoURL type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array syncPolicy: properties: automated: @@ -1592,7 +2393,6 @@ spec: required: - destination - project - - source type: object required: - metadata @@ -1854,6 +2654,8 @@ spec: type: object type: array type: object + ref: + type: string repoURL: type: string targetRevision: @@ -1861,6 +2663,165 @@ spec: required: - repoURL type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array syncPolicy: properties: automated: @@ -1907,7 +2868,6 @@ spec: required: - destination - project - - source type: object required: - metadata @@ -2173,6 +3133,8 @@ spec: type: object type: array type: object + ref: + type: string repoURL: type: string targetRevision: @@ -2180,6 +3142,165 @@ spec: required: - repoURL type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array syncPolicy: properties: automated: @@ -2226,7 +3347,6 @@ spec: required: - destination - project - - source type: object required: - metadata @@ -2467,6 +3587,8 @@ spec: type: object type: array type: object + ref: + type: string repoURL: type: string targetRevision: @@ -2474,6 +3596,165 @@ spec: required: - repoURL type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array syncPolicy: properties: automated: @@ -2520,7 +3801,6 @@ spec: required: - destination - project - - source type: object required: - metadata @@ -2878,6 +4158,8 @@ spec: type: object type: array type: object + ref: + type: string repoURL: type: string targetRevision: @@ -2885,6 +4167,165 @@ spec: required: - repoURL type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array syncPolicy: properties: automated: @@ -2931,7 +4372,6 @@ spec: required: - destination - project - - source type: object required: - metadata @@ -3336,6 +4776,8 @@ spec: type: object type: array type: object + ref: + type: string repoURL: type: string targetRevision: @@ -3343,6 +4785,165 @@ spec: required: - repoURL type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array syncPolicy: properties: automated: @@ -3389,7 +4990,6 @@ spec: required: - destination - project - - source type: object required: - metadata @@ -3593,65 +5193,226 @@ spec: commonLabels: additionalProperties: type: string - type: object - forceCommonAnnotations: - type: boolean - forceCommonLabels: - type: boolean - images: - items: + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: type: string - type: array - namePrefix: - type: string - nameSuffix: - type: string - version: - type: string - type: object - path: - type: string - plugin: - properties: - env: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - name: - type: string - parameters: - items: - properties: - array: - items: + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: type: string - type: array - map: - additionalProperties: + string: type: string - type: object - name: - type: string - string: - type: string - type: object - type: array - type: object - repoURL: - type: string - targetRevision: - type: string - required: - - repoURL - type: object + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array syncPolicy: properties: automated: @@ -3698,7 +5459,6 @@ spec: required: - destination - project - - source type: object required: - metadata @@ -3968,6 +5728,8 @@ spec: type: object type: array type: object + ref: + type: string repoURL: type: string targetRevision: @@ -3975,6 +5737,165 @@ spec: required: - repoURL type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array syncPolicy: properties: automated: @@ -4021,7 +5942,6 @@ spec: required: - destination - project - - source type: object required: - metadata @@ -4283,6 +6203,8 @@ spec: type: object type: array type: object + ref: + type: string repoURL: type: string targetRevision: @@ -4290,6 +6212,165 @@ spec: required: - repoURL type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array syncPolicy: properties: automated: @@ -4336,7 +6417,6 @@ spec: required: - destination - project - - source type: object required: - metadata @@ -4602,6 +6682,8 @@ spec: type: object type: array type: object + ref: + type: string repoURL: type: string targetRevision: @@ -4609,6 +6691,165 @@ spec: required: - repoURL type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array syncPolicy: properties: automated: @@ -4655,7 +6896,6 @@ spec: required: - destination - project - - source type: object required: - metadata @@ -4896,6 +7136,8 @@ spec: type: object type: array type: object + ref: + type: string repoURL: type: string targetRevision: @@ -4903,6 +7145,165 @@ spec: required: - repoURL type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array syncPolicy: properties: automated: @@ -4949,7 +7350,6 @@ spec: required: - destination - project - - source type: object required: - metadata @@ -5307,6 +7707,8 @@ spec: type: object type: array type: object + ref: + type: string repoURL: type: string targetRevision: @@ -5314,6 +7716,165 @@ spec: required: - repoURL type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array syncPolicy: properties: automated: @@ -5360,7 +7921,6 @@ spec: required: - destination - project - - source type: object required: - metadata @@ -5765,6 +8325,8 @@ spec: type: object type: array type: object + ref: + type: string repoURL: type: string targetRevision: @@ -5772,6 +8334,165 @@ spec: required: - repoURL type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array syncPolicy: properties: automated: @@ -5818,7 +8539,6 @@ spec: required: - destination - project - - source type: object required: - metadata @@ -6078,6 +8798,8 @@ spec: type: object type: array type: object + ref: + type: string repoURL: type: string targetRevision: @@ -6085,6 +8807,165 @@ spec: required: - repoURL type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array syncPolicy: properties: automated: @@ -6131,7 +9012,6 @@ spec: required: - destination - project - - source type: object required: - metadata @@ -6474,25 +9354,186 @@ spec: array: items: type: string - type: array - map: - additionalProperties: + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: type: string - type: object - name: - type: string - string: - type: string - type: object - type: array - type: object - repoURL: - type: string - targetRevision: - type: string - required: - - repoURL - type: object + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array syncPolicy: properties: automated: @@ -6539,7 +9580,6 @@ spec: required: - destination - project - - source type: object required: - metadata @@ -6944,6 +9984,8 @@ spec: type: object type: array type: object + ref: + type: string repoURL: type: string targetRevision: @@ -6951,6 +9993,165 @@ spec: required: - repoURL type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array syncPolicy: properties: automated: @@ -6997,7 +10198,6 @@ spec: required: - destination - project - - source type: object required: - metadata @@ -7260,6 +10460,8 @@ spec: type: object type: array type: object + ref: + type: string repoURL: type: string targetRevision: @@ -7267,6 +10469,165 @@ spec: required: - repoURL type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array syncPolicy: properties: automated: @@ -7313,7 +10674,6 @@ spec: required: - destination - project - - source type: object required: - metadata diff --git a/manifests/ha/install.yaml b/manifests/ha/install.yaml index 9526b4a3c735c..6cecdbd529924 100644 --- a/manifests/ha/install.yaml +++ b/manifests/ha/install.yaml @@ -144,6 +144,14 @@ spec: which to sync the application to If omitted, will use the revision specified in app spec. type: string + revisions: + description: Revisions is the list of revision (Git) or chart + version (Helm) which to sync each source in sources field for + the application to If omitted, will use the revision specified + in app spec. + items: + type: string + type: array source: description: Source overrides the source definition set in the application. This is typically set in a Rollback operation and @@ -383,6 +391,11 @@ spec: type: object type: array type: object + ref: + description: Ref is reference to another source within sources + field. This field will not be used if used with a `source` + tag. + type: string repoURL: description: RepoURL is the URL to the repository (Git or Helm) that contains the application manifests @@ -396,510 +409,1042 @@ spec: required: - repoURL type: object - syncOptions: - description: SyncOptions provide per-sync sync-options, e.g. Validate=false + sources: + description: Sources overrides the source definition set in the + application. This is typically set in a Rollback operation and + is nil during a Sync operation items: - type: string - type: array - syncStrategy: - description: SyncStrategy describes how to perform the sync - properties: - apply: - description: Apply will perform a `kubectl apply` to perform - the sync. - properties: - force: - description: Force indicates whether or not to supply - the --force flag to `kubectl apply`. The --force flag - deletes and re-create the resource, when PATCH encounters - conflict and has retried for 5 times. - type: boolean - type: object - hook: - description: Hook will submit any referenced resources to - perform the sync. This is the default strategy - properties: - force: - description: Force indicates whether or not to supply - the --force flag to `kubectl apply`. The --force flag - deletes and re-create the resource, when PATCH encounters - conflict and has retried for 5 times. - type: boolean - type: object - type: object - type: object - type: object - spec: - description: ApplicationSpec represents desired application state. Contains - link to repository with application definition and additional parameters - link definition revision. - properties: - destination: - description: Destination is a reference to the target Kubernetes server - and namespace - properties: - name: - description: Name is an alternate way of specifying the target - cluster by its symbolic name - type: string - namespace: - description: Namespace specifies the target namespace for the - application's resources. The namespace will only be set for - namespace-scoped resources that have not set a value for .metadata.namespace - type: string - server: - description: Server specifies the URL of the target cluster and - must be set to the Kubernetes control plane API - type: string - type: object - ignoreDifferences: - description: IgnoreDifferences is a list of resources and their fields - which should be ignored during comparison - items: - description: ResourceIgnoreDifferences contains resource filter - and list of json paths which should be ignored during comparison - with live state. - properties: - group: - type: string - jqPathExpressions: - items: - type: string - type: array - jsonPointers: - items: - type: string - type: array - kind: - type: string - managedFieldsManagers: - description: ManagedFieldsManagers is a list of trusted managers. - Fields mutated by those managers will take precedence over - the desired state defined in the SCM and won't be displayed - in diffs - items: - type: string - type: array - name: - type: string - namespace: - type: string - required: - - kind - type: object - type: array - info: - description: Info contains a list of information (URLs, email addresses, - and plain text) that relates to the application - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - project: - description: Project is a reference to the project this application - belongs to. The empty string means that application belongs to the - 'default' project. - type: string - revisionHistoryLimit: - description: RevisionHistoryLimit limits the number of items kept - in the application's revision history, which is used for informational - purposes as well as for rollbacks to previous versions. This should - only be changed in exceptional circumstances. Setting to zero will - store no history. This will reduce storage used. Increasing will - increase the space used to store the history, so we do not recommend - increasing it. Default is 10. - format: int64 - type: integer - source: - description: Source is a reference to the location of the application's - manifests or chart - properties: - chart: - description: Chart is a Helm chart name, and must be specified - for applications sourced from a Helm repo. - type: string - directory: - description: Directory holds path/directory specific options - properties: - exclude: - description: Exclude contains a glob pattern to match paths - against that should be explicitly excluded from being used - during manifest generation - type: string - include: - description: Include contains a glob pattern to match paths - against that should be explicitly included during manifest - generation - type: string - jsonnet: - description: Jsonnet holds options specific to Jsonnet - properties: - extVars: - description: ExtVars is a list of Jsonnet External Variables - items: - description: JsonnetVar represents a variable to be - passed to jsonnet during manifest generation - properties: - code: - type: boolean - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - libs: - description: Additional library search dirs - items: - type: string - type: array - tlas: - description: TLAS is a list of Jsonnet Top-level Arguments - items: - description: JsonnetVar represents a variable to be - passed to jsonnet during manifest generation - properties: - code: - type: boolean - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - type: object - recurse: - description: Recurse specifies whether to scan a directory - recursively for manifests - type: boolean - type: object - helm: - description: Helm holds helm specific options - properties: - fileParameters: - description: FileParameters are file parameters to the helm - template - items: - description: HelmFileParameter is a file parameter that's - passed to helm template during manifest generation - properties: - name: - description: Name is the name of the Helm parameter - type: string - path: - description: Path is the path to the file containing - the values for the Helm parameter - type: string - type: object - type: array - ignoreMissingValueFiles: - description: IgnoreMissingValueFiles prevents helm template - from failing when valueFiles do not exist locally by not - appending them to helm template --values - type: boolean - parameters: - description: Parameters is a list of Helm parameters which - are passed to the helm template command upon manifest generation - items: - description: HelmParameter is a parameter that's passed - to helm template during manifest generation + description: ApplicationSource contains all required information + about the source of an application + properties: + chart: + description: Chart is a Helm chart name, and must be specified + for applications sourced from a Helm repo. + type: string + directory: + description: Directory holds path/directory specific options properties: - forceString: - description: ForceString determines whether to tell - Helm to interpret booleans and numbers as strings - type: boolean - name: - description: Name is the name of the Helm parameter + exclude: + description: Exclude contains a glob pattern to match + paths against that should be explicitly excluded from + being used during manifest generation type: string - value: - description: Value is the value for the Helm parameter + include: + description: Include contains a glob pattern to match + paths against that should be explicitly included during + manifest generation type: string - type: object - type: array - passCredentials: - description: PassCredentials pass credentials to all domains - (Helm's --pass-credentials) - type: boolean - releaseName: - description: ReleaseName is the Helm release name to use. - If omitted it will use the application name - type: string - skipCrds: - description: SkipCrds skips custom resource definition installation - step (Helm's --skip-crds) - type: boolean - valueFiles: - description: ValuesFiles is a list of Helm value files to - use when generating a template - items: - type: string - type: array - values: - description: Values specifies Helm values to be passed to - helm template, typically defined as a block - type: string - version: - description: Version is the Helm version to use for templating - ("3") - type: string - type: object - kustomize: - description: Kustomize holds kustomize specific options - properties: - commonAnnotations: - additionalProperties: - type: string - description: CommonAnnotations is a list of additional annotations - to add to rendered manifests - type: object - commonLabels: - additionalProperties: - type: string - description: CommonLabels is a list of additional labels to - add to rendered manifests - type: object - forceCommonAnnotations: - description: ForceCommonAnnotations specifies whether to force - applying common annotations to resources for Kustomize apps - type: boolean - forceCommonLabels: - description: ForceCommonLabels specifies whether to force - applying common labels to resources for Kustomize apps - type: boolean - images: - description: Images is a list of Kustomize image override - specifications - items: - description: KustomizeImage represents a Kustomize image - definition in the format [old_image_name=]: - type: string - type: array - namePrefix: - description: NamePrefix is a prefix appended to resources - for Kustomize apps - type: string - nameSuffix: - description: NameSuffix is a suffix appended to resources - for Kustomize apps - type: string - version: - description: Version controls which version of Kustomize to - use for rendering manifests - type: string - type: object - path: - description: Path is a directory path within the Git repository, - and is only valid for applications sourced from Git. - type: string - plugin: - description: Plugin holds config management plugin specific options - properties: - env: - description: Env is a list of environment variable entries - items: - description: EnvEntry represents an entry in the application's - environment + jsonnet: + description: Jsonnet holds options specific to Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet External + Variables + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level + Arguments + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan a directory + recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options properties: - name: - description: Name is the name of the variable, usually - expressed in uppercase + fileParameters: + description: FileParameters are file parameters to the + helm template + items: + description: HelmFileParameter is a file parameter + that's passed to helm template during manifest generation + properties: + name: + description: Name is the name of the Helm parameter + type: string + path: + description: Path is the path to the file containing + the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents helm template + from failing when valueFiles do not exist locally + by not appending them to helm template --values + type: boolean + parameters: + description: Parameters is a list of Helm parameters + which are passed to the helm template command upon + manifest generation + items: + description: HelmParameter is a parameter that's passed + to helm template during manifest generation + properties: + forceString: + description: ForceString determines whether to + tell Helm to interpret booleans and numbers + as strings + type: boolean + name: + description: Name is the name of the Helm parameter + type: string + value: + description: Value is the value for the Helm parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials to all + domains (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release name to + use. If omitted it will use the application name type: string - value: - description: Value is the value of the variable + skipCrds: + description: SkipCrds skips custom resource definition + installation step (Helm's --skip-crds) + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value files + to use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to be passed + to helm template, typically defined as a block + type: string + version: + description: Version is the Helm version to use for + templating ("3") type: string - required: - - name - - value type: object - type: array - name: - type: string - parameters: - items: + kustomize: + description: Kustomize holds kustomize specific options properties: - array: - description: Array is the value of an array type parameter. - items: + commonAnnotations: + additionalProperties: type: string - type: array - map: + description: CommonAnnotations is a list of additional + annotations to add to rendered manifests + type: object + commonLabels: additionalProperties: type: string - description: Map is the value of a map type parameter. + description: CommonLabels is a list of additional labels + to add to rendered manifests type: object - name: - description: Name is the name identifying a parameter. + forceCommonAnnotations: + description: ForceCommonAnnotations specifies whether + to force applying common annotations to resources + for Kustomize apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether to + force applying common labels to resources for Kustomize + apps + type: boolean + images: + description: Images is a list of Kustomize image override + specifications + items: + description: KustomizeImage represents a Kustomize + image definition in the format [old_image_name=]: + type: string + type: array + namePrefix: + description: NamePrefix is a prefix appended to resources + for Kustomize apps type: string - string: - description: String_ is the value of a string type parameter. + nameSuffix: + description: NameSuffix is a suffix appended to resources + for Kustomize apps + type: string + version: + description: Version controls which version of Kustomize + to use for rendering manifests type: string type: object - type: array - type: object - repoURL: - description: RepoURL is the URL to the repository (Git or Helm) - that contains the application manifests - type: string - targetRevision: - description: TargetRevision defines the revision of the source - to sync the application to. In case of Git, this can be commit, - tag, or branch. If omitted, will equal to HEAD. In case of Helm, - this is a semver tag for the Chart's version. - type: string - required: - - repoURL - type: object - syncPolicy: - description: SyncPolicy controls when and how a sync will be performed - properties: - automated: - description: Automated will keep an application synced to the - target revision - properties: - allowEmpty: - description: 'AllowEmpty allows apps have zero live resources - (default: false)' - type: boolean - prune: - description: 'Prune specifies whether to delete resources - from the cluster that are not found in the sources anymore - as part of automated sync (default: false)' - type: boolean - selfHeal: - description: 'SelfHeal specifes whether to revert resources - back to their desired state upon modification in the cluster - (default: false)' - type: boolean - type: object - managedNamespaceMetadata: - description: ManagedNamespaceMetadata controls metadata in the - given namespace (if CreateNamespace=true) - properties: - annotations: - additionalProperties: + path: + description: Path is a directory path within the Git repository, + and is only valid for applications sourced from Git. type: string - type: object - labels: - additionalProperties: + plugin: + description: Plugin holds config management plugin specific + options + properties: + env: + description: Env is a list of environment variable entries + items: + description: EnvEntry represents an entry in the application's + environment + properties: + name: + description: Name is the name of the variable, + usually expressed in uppercase + type: string + value: + description: Value is the value of the variable + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + description: Array is the value of an array type + parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map type parameter. + type: object + name: + description: Name is the name identifying a parameter. + type: string + string: + description: String_ is the value of a string + type parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source within sources + field. This field will not be used if used with a `source` + tag. type: string - type: object - type: object - retry: - description: Retry controls failed sync retry behavior - properties: - backoff: - description: Backoff controls how to backoff on subsequent - retries of failed syncs - properties: - duration: - description: Duration is the amount to back off. Default - unit is seconds, but could also be a duration (e.g. - "2m", "1h") - type: string - factor: - description: Factor is a factor to multiply the base duration - after each failed retry - format: int64 - type: integer - maxDuration: - description: MaxDuration is the maximum amount of time - allowed for the backoff strategy - type: string - type: object - limit: - description: Limit is the maximum number of attempts for retrying - a failed sync. If set to 0, no retries will be performed. - format: int64 - type: integer - type: object + repoURL: + description: RepoURL is the URL to the repository (Git or + Helm) that contains the application manifests + type: string + targetRevision: + description: TargetRevision defines the revision of the + source to sync the application to. In case of Git, this + can be commit, tag, or branch. If omitted, will equal + to HEAD. In case of Helm, this is a semver tag for the + Chart's version. + type: string + required: + - repoURL + type: object + type: array syncOptions: - description: Options allow you to specify whole app sync-options + description: SyncOptions provide per-sync sync-options, e.g. Validate=false items: type: string type: array + syncStrategy: + description: SyncStrategy describes how to perform the sync + properties: + apply: + description: Apply will perform a `kubectl apply` to perform + the sync. + properties: + force: + description: Force indicates whether or not to supply + the --force flag to `kubectl apply`. The --force flag + deletes and re-create the resource, when PATCH encounters + conflict and has retried for 5 times. + type: boolean + type: object + hook: + description: Hook will submit any referenced resources to + perform the sync. This is the default strategy + properties: + force: + description: Force indicates whether or not to supply + the --force flag to `kubectl apply`. The --force flag + deletes and re-create the resource, when PATCH encounters + conflict and has retried for 5 times. + type: boolean + type: object + type: object type: object - required: - - destination - - project - - source type: object - status: - description: ApplicationStatus contains status information for the application + spec: + description: ApplicationSpec represents desired application state. Contains + link to repository with application definition and additional parameters + link definition revision. properties: - conditions: - description: Conditions is a list of currently observed application - conditions - items: - description: ApplicationCondition contains details about an application - condition, which is usally an error or warning - properties: - lastTransitionTime: - description: LastTransitionTime is the time the condition was - last observed - format: date-time - type: string - message: - description: Message contains human-readable message indicating - details about condition - type: string - type: - description: Type is an application condition type - type: string - required: - - message - - type - type: object - type: array - health: - description: Health contains information about the application's current - health status + destination: + description: Destination is a reference to the target Kubernetes server + and namespace properties: - message: - description: Message is a human-readable informational message - describing the health status + name: + description: Name is an alternate way of specifying the target + cluster by its symbolic name type: string - status: - description: Status holds the status code of the application or - resource + namespace: + description: Namespace specifies the target namespace for the + application's resources. The namespace will only be set for + namespace-scoped resources that have not set a value for .metadata.namespace + type: string + server: + description: Server specifies the URL of the target cluster and + must be set to the Kubernetes control plane API type: string type: object - history: - description: History contains information about the application's - sync history + ignoreDifferences: + description: IgnoreDifferences is a list of resources and their fields + which should be ignored during comparison items: - description: RevisionHistory contains history information about - a previous sync + description: ResourceIgnoreDifferences contains resource filter + and list of json paths which should be ignored during comparison + with live state. properties: - deployStartedAt: - description: DeployStartedAt holds the time the sync operation - started - format: date-time + group: type: string - deployedAt: - description: DeployedAt holds the time the sync operation completed - format: date-time + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: type: string - id: - description: ID is an auto incrementing identifier of the RevisionHistory + managedFieldsManagers: + description: ManagedFieldsManagers is a list of trusted managers. + Fields mutated by those managers will take precedence over + the desired state defined in the SCM and won't be displayed + in diffs + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + description: Info contains a list of information (URLs, email addresses, + and plain text) that relates to the application + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + description: Project is a reference to the project this application + belongs to. The empty string means that application belongs to the + 'default' project. + type: string + revisionHistoryLimit: + description: RevisionHistoryLimit limits the number of items kept + in the application's revision history, which is used for informational + purposes as well as for rollbacks to previous versions. This should + only be changed in exceptional circumstances. Setting to zero will + store no history. This will reduce storage used. Increasing will + increase the space used to store the history, so we do not recommend + increasing it. Default is 10. + format: int64 + type: integer + source: + description: Source is a reference to the location of the application's + manifests or chart + properties: + chart: + description: Chart is a Helm chart name, and must be specified + for applications sourced from a Helm repo. + type: string + directory: + description: Directory holds path/directory specific options + properties: + exclude: + description: Exclude contains a glob pattern to match paths + against that should be explicitly excluded from being used + during manifest generation + type: string + include: + description: Include contains a glob pattern to match paths + against that should be explicitly included during manifest + generation + type: string + jsonnet: + description: Jsonnet holds options specific to Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet External Variables + items: + description: JsonnetVar represents a variable to be + passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level Arguments + items: + description: JsonnetVar represents a variable to be + passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan a directory + recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options + properties: + fileParameters: + description: FileParameters are file parameters to the helm + template + items: + description: HelmFileParameter is a file parameter that's + passed to helm template during manifest generation + properties: + name: + description: Name is the name of the Helm parameter + type: string + path: + description: Path is the path to the file containing + the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents helm template + from failing when valueFiles do not exist locally by not + appending them to helm template --values + type: boolean + parameters: + description: Parameters is a list of Helm parameters which + are passed to the helm template command upon manifest generation + items: + description: HelmParameter is a parameter that's passed + to helm template during manifest generation + properties: + forceString: + description: ForceString determines whether to tell + Helm to interpret booleans and numbers as strings + type: boolean + name: + description: Name is the name of the Helm parameter + type: string + value: + description: Value is the value for the Helm parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials to all domains + (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release name to use. + If omitted it will use the application name + type: string + skipCrds: + description: SkipCrds skips custom resource definition installation + step (Helm's --skip-crds) + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value files to + use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to be passed to + helm template, typically defined as a block + type: string + version: + description: Version is the Helm version to use for templating + ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific options + properties: + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of additional annotations + to add to rendered manifests + type: object + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional labels to + add to rendered manifests + type: object + forceCommonAnnotations: + description: ForceCommonAnnotations specifies whether to force + applying common annotations to resources for Kustomize apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether to force + applying common labels to resources for Kustomize apps + type: boolean + images: + description: Images is a list of Kustomize image override + specifications + items: + description: KustomizeImage represents a Kustomize image + definition in the format [old_image_name=]: + type: string + type: array + namePrefix: + description: NamePrefix is a prefix appended to resources + for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended to resources + for Kustomize apps + type: string + version: + description: Version controls which version of Kustomize to + use for rendering manifests + type: string + type: object + path: + description: Path is a directory path within the Git repository, + and is only valid for applications sourced from Git. + type: string + plugin: + description: Plugin holds config management plugin specific options + properties: + env: + description: Env is a list of environment variable entries + items: + description: EnvEntry represents an entry in the application's + environment + properties: + name: + description: Name is the name of the variable, usually + expressed in uppercase + type: string + value: + description: Value is the value of the variable + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + description: Array is the value of an array type parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map type parameter. + type: object + name: + description: Name is the name identifying a parameter. + type: string + string: + description: String_ is the value of a string type parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source within sources + field. This field will not be used if used with a `source` tag. + type: string + repoURL: + description: RepoURL is the URL to the repository (Git or Helm) + that contains the application manifests + type: string + targetRevision: + description: TargetRevision defines the revision of the source + to sync the application to. In case of Git, this can be commit, + tag, or branch. If omitted, will equal to HEAD. In case of Helm, + this is a semver tag for the Chart's version. + type: string + required: + - repoURL + type: object + sources: + description: Sources is a reference to the location of the application's + manifests or chart + items: + description: ApplicationSource contains all required information + about the source of an application + properties: + chart: + description: Chart is a Helm chart name, and must be specified + for applications sourced from a Helm repo. + type: string + directory: + description: Directory holds path/directory specific options + properties: + exclude: + description: Exclude contains a glob pattern to match paths + against that should be explicitly excluded from being + used during manifest generation + type: string + include: + description: Include contains a glob pattern to match paths + against that should be explicitly included during manifest + generation + type: string + jsonnet: + description: Jsonnet holds options specific to Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet External Variables + items: + description: JsonnetVar represents a variable to be + passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level Arguments + items: + description: JsonnetVar represents a variable to be + passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan a directory + recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options + properties: + fileParameters: + description: FileParameters are file parameters to the helm + template + items: + description: HelmFileParameter is a file parameter that's + passed to helm template during manifest generation + properties: + name: + description: Name is the name of the Helm parameter + type: string + path: + description: Path is the path to the file containing + the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents helm template + from failing when valueFiles do not exist locally by not + appending them to helm template --values + type: boolean + parameters: + description: Parameters is a list of Helm parameters which + are passed to the helm template command upon manifest + generation + items: + description: HelmParameter is a parameter that's passed + to helm template during manifest generation + properties: + forceString: + description: ForceString determines whether to tell + Helm to interpret booleans and numbers as strings + type: boolean + name: + description: Name is the name of the Helm parameter + type: string + value: + description: Value is the value for the Helm parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials to all domains + (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release name to use. + If omitted it will use the application name + type: string + skipCrds: + description: SkipCrds skips custom resource definition installation + step (Helm's --skip-crds) + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value files to + use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to be passed to + helm template, typically defined as a block + type: string + version: + description: Version is the Helm version to use for templating + ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific options + properties: + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of additional annotations + to add to rendered manifests + type: object + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional labels + to add to rendered manifests + type: object + forceCommonAnnotations: + description: ForceCommonAnnotations specifies whether to + force applying common annotations to resources for Kustomize + apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether to force + applying common labels to resources for Kustomize apps + type: boolean + images: + description: Images is a list of Kustomize image override + specifications + items: + description: KustomizeImage represents a Kustomize image + definition in the format [old_image_name=]: + type: string + type: array + namePrefix: + description: NamePrefix is a prefix appended to resources + for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended to resources + for Kustomize apps + type: string + version: + description: Version controls which version of Kustomize + to use for rendering manifests + type: string + type: object + path: + description: Path is a directory path within the Git repository, + and is only valid for applications sourced from Git. + type: string + plugin: + description: Plugin holds config management plugin specific + options + properties: + env: + description: Env is a list of environment variable entries + items: + description: EnvEntry represents an entry in the application's + environment + properties: + name: + description: Name is the name of the variable, usually + expressed in uppercase + type: string + value: + description: Value is the value of the variable + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + description: Array is the value of an array type parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map type parameter. + type: object + name: + description: Name is the name identifying a parameter. + type: string + string: + description: String_ is the value of a string type + parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source within sources + field. This field will not be used if used with a `source` + tag. + type: string + repoURL: + description: RepoURL is the URL to the repository (Git or Helm) + that contains the application manifests + type: string + targetRevision: + description: TargetRevision defines the revision of the source + to sync the application to. In case of Git, this can be commit, + tag, or branch. If omitted, will equal to HEAD. In case of + Helm, this is a semver tag for the Chart's version. + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + description: SyncPolicy controls when and how a sync will be performed + properties: + automated: + description: Automated will keep an application synced to the + target revision + properties: + allowEmpty: + description: 'AllowEmpty allows apps have zero live resources + (default: false)' + type: boolean + prune: + description: 'Prune specifies whether to delete resources + from the cluster that are not found in the sources anymore + as part of automated sync (default: false)' + type: boolean + selfHeal: + description: 'SelfHeal specifes whether to revert resources + back to their desired state upon modification in the cluster + (default: false)' + type: boolean + type: object + managedNamespaceMetadata: + description: ManagedNamespaceMetadata controls metadata in the + given namespace (if CreateNamespace=true) + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + description: Retry controls failed sync retry behavior + properties: + backoff: + description: Backoff controls how to backoff on subsequent + retries of failed syncs + properties: + duration: + description: Duration is the amount to back off. Default + unit is seconds, but could also be a duration (e.g. + "2m", "1h") + type: string + factor: + description: Factor is a factor to multiply the base duration + after each failed retry + format: int64 + type: integer + maxDuration: + description: MaxDuration is the maximum amount of time + allowed for the backoff strategy + type: string + type: object + limit: + description: Limit is the maximum number of attempts for retrying + a failed sync. If set to 0, no retries will be performed. + format: int64 + type: integer + type: object + syncOptions: + description: Options allow you to specify whole app sync-options + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + status: + description: ApplicationStatus contains status information for the application + properties: + conditions: + description: Conditions is a list of currently observed application + conditions + items: + description: ApplicationCondition contains details about an application + condition, which is usally an error or warning + properties: + lastTransitionTime: + description: LastTransitionTime is the time the condition was + last observed + format: date-time + type: string + message: + description: Message contains human-readable message indicating + details about condition + type: string + type: + description: Type is an application condition type + type: string + required: + - message + - type + type: object + type: array + health: + description: Health contains information about the application's current + health status + properties: + message: + description: Message is a human-readable informational message + describing the health status + type: string + status: + description: Status holds the status code of the application or + resource + type: string + type: object + history: + description: History contains information about the application's + sync history + items: + description: RevisionHistory contains history information about + a previous sync + properties: + deployStartedAt: + description: DeployStartedAt holds the time the sync operation + started + format: date-time + type: string + deployedAt: + description: DeployedAt holds the time the sync operation completed + format: date-time + type: string + id: + description: ID is an auto incrementing identifier of the RevisionHistory format: int64 type: integer revision: description: Revision holds the revision the sync was performed against type: string + revisions: + description: Revisions holds the revision of each source in + sources field the sync was performed against + items: + type: string + type: array source: description: Source is a reference to the application source used for the sync operation @@ -1016,149 +1561,422 @@ spec: type: string type: object type: array - passCredentials: - description: PassCredentials pass credentials to all - domains (Helm's --pass-credentials) - type: boolean - releaseName: - description: ReleaseName is the Helm release name to - use. If omitted it will use the application name + passCredentials: + description: PassCredentials pass credentials to all + domains (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release name to + use. If omitted it will use the application name + type: string + skipCrds: + description: SkipCrds skips custom resource definition + installation step (Helm's --skip-crds) + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value files + to use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to be passed + to helm template, typically defined as a block + type: string + version: + description: Version is the Helm version to use for + templating ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific options + properties: + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of additional + annotations to add to rendered manifests + type: object + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional labels + to add to rendered manifests + type: object + forceCommonAnnotations: + description: ForceCommonAnnotations specifies whether + to force applying common annotations to resources + for Kustomize apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether to + force applying common labels to resources for Kustomize + apps + type: boolean + images: + description: Images is a list of Kustomize image override + specifications + items: + description: KustomizeImage represents a Kustomize + image definition in the format [old_image_name=]: + type: string + type: array + namePrefix: + description: NamePrefix is a prefix appended to resources + for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended to resources + for Kustomize apps + type: string + version: + description: Version controls which version of Kustomize + to use for rendering manifests + type: string + type: object + path: + description: Path is a directory path within the Git repository, + and is only valid for applications sourced from Git. + type: string + plugin: + description: Plugin holds config management plugin specific + options + properties: + env: + description: Env is a list of environment variable entries + items: + description: EnvEntry represents an entry in the application's + environment + properties: + name: + description: Name is the name of the variable, + usually expressed in uppercase + type: string + value: + description: Value is the value of the variable + type: string + required: + - name + - value + type: object + type: array + name: type: string - skipCrds: - description: SkipCrds skips custom resource definition - installation step (Helm's --skip-crds) - type: boolean - valueFiles: - description: ValuesFiles is a list of Helm value files - to use when generating a template + parameters: items: - type: string + properties: + array: + description: Array is the value of an array type + parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map type parameter. + type: object + name: + description: Name is the name identifying a parameter. + type: string + string: + description: String_ is the value of a string + type parameter. + type: string + type: object type: array - values: - description: Values specifies Helm values to be passed - to helm template, typically defined as a block - type: string - version: - description: Version is the Helm version to use for - templating ("3") - type: string type: object - kustomize: - description: Kustomize holds kustomize specific options - properties: - commonAnnotations: - additionalProperties: + ref: + description: Ref is reference to another source within sources + field. This field will not be used if used with a `source` + tag. + type: string + repoURL: + description: RepoURL is the URL to the repository (Git or + Helm) that contains the application manifests + type: string + targetRevision: + description: TargetRevision defines the revision of the + source to sync the application to. In case of Git, this + can be commit, tag, or branch. If omitted, will equal + to HEAD. In case of Helm, this is a semver tag for the + Chart's version. + type: string + required: + - repoURL + type: object + sources: + description: Sources is a reference to the application sources + used for the sync operation + items: + description: ApplicationSource contains all required information + about the source of an application + properties: + chart: + description: Chart is a Helm chart name, and must be specified + for applications sourced from a Helm repo. + type: string + directory: + description: Directory holds path/directory specific options + properties: + exclude: + description: Exclude contains a glob pattern to match + paths against that should be explicitly excluded + from being used during manifest generation type: string - description: CommonAnnotations is a list of additional - annotations to add to rendered manifests - type: object - commonLabels: - additionalProperties: + include: + description: Include contains a glob pattern to match + paths against that should be explicitly included + during manifest generation + type: string + jsonnet: + description: Jsonnet holds options specific to Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet External + Variables + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level + Arguments + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan a directory + recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options + properties: + fileParameters: + description: FileParameters are file parameters to + the helm template + items: + description: HelmFileParameter is a file parameter + that's passed to helm template during manifest + generation + properties: + name: + description: Name is the name of the Helm parameter + type: string + path: + description: Path is the path to the file containing + the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents helm + template from failing when valueFiles do not exist + locally by not appending them to helm template --values + type: boolean + parameters: + description: Parameters is a list of Helm parameters + which are passed to the helm template command upon + manifest generation + items: + description: HelmParameter is a parameter that's + passed to helm template during manifest generation + properties: + forceString: + description: ForceString determines whether + to tell Helm to interpret booleans and numbers + as strings + type: boolean + name: + description: Name is the name of the Helm parameter + type: string + value: + description: Value is the value for the Helm + parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials to all + domains (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release name + to use. If omitted it will use the application name + type: string + skipCrds: + description: SkipCrds skips custom resource definition + installation step (Helm's --skip-crds) + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value files + to use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to be passed + to helm template, typically defined as a block + type: string + version: + description: Version is the Helm version to use for + templating ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific options + properties: + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of additional + annotations to add to rendered manifests + type: object + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional + labels to add to rendered manifests + type: object + forceCommonAnnotations: + description: ForceCommonAnnotations specifies whether + to force applying common annotations to resources + for Kustomize apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether to + force applying common labels to resources for Kustomize + apps + type: boolean + images: + description: Images is a list of Kustomize image override + specifications + items: + description: KustomizeImage represents a Kustomize + image definition in the format [old_image_name=]: + type: string + type: array + namePrefix: + description: NamePrefix is a prefix appended to resources + for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended to resources + for Kustomize apps + type: string + version: + description: Version controls which version of Kustomize + to use for rendering manifests type: string - description: CommonLabels is a list of additional labels - to add to rendered manifests - type: object - forceCommonAnnotations: - description: ForceCommonAnnotations specifies whether - to force applying common annotations to resources - for Kustomize apps - type: boolean - forceCommonLabels: - description: ForceCommonLabels specifies whether to - force applying common labels to resources for Kustomize - apps - type: boolean - images: - description: Images is a list of Kustomize image override - specifications - items: - description: KustomizeImage represents a Kustomize - image definition in the format [old_image_name=]: + type: object + path: + description: Path is a directory path within the Git repository, + and is only valid for applications sourced from Git. + type: string + plugin: + description: Plugin holds config management plugin specific + options + properties: + env: + description: Env is a list of environment variable + entries + items: + description: EnvEntry represents an entry in the + application's environment + properties: + name: + description: Name is the name of the variable, + usually expressed in uppercase + type: string + value: + description: Value is the value of the variable + type: string + required: + - name + - value + type: object + type: array + name: type: string - type: array - namePrefix: - description: NamePrefix is a prefix appended to resources - for Kustomize apps - type: string - nameSuffix: - description: NameSuffix is a suffix appended to resources - for Kustomize apps - type: string - version: - description: Version controls which version of Kustomize - to use for rendering manifests - type: string - type: object - path: - description: Path is a directory path within the Git repository, - and is only valid for applications sourced from Git. - type: string - plugin: - description: Plugin holds config management plugin specific - options - properties: - env: - description: Env is a list of environment variable entries - items: - description: EnvEntry represents an entry in the application's - environment - properties: - name: - description: Name is the name of the variable, - usually expressed in uppercase - type: string - value: - description: Value is the value of the variable - type: string - required: - - name - - value - type: object - type: array - name: - type: string - parameters: - items: - properties: - array: - description: Array is the value of an array type - parameter. - items: + parameters: + items: + properties: + array: + description: Array is the value of an array + type parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map type + parameter. + type: object + name: + description: Name is the name identifying a + parameter. type: string - type: array - map: - additionalProperties: + string: + description: String_ is the value of a string + type parameter. type: string - description: Map is the value of a map type parameter. - type: object - name: - description: Name is the name identifying a parameter. - type: string - string: - description: String_ is the value of a string - type parameter. - type: string - type: object - type: array - type: object - repoURL: - description: RepoURL is the URL to the repository (Git or - Helm) that contains the application manifests - type: string - targetRevision: - description: TargetRevision defines the revision of the - source to sync the application to. In case of Git, this - can be commit, tag, or branch. If omitted, will equal - to HEAD. In case of Helm, this is a semver tag for the - Chart's version. - type: string - required: - - repoURL - type: object + type: object + type: array + type: object + ref: + description: Ref is reference to another source within + sources field. This field will not be used if used with + a `source` tag. + type: string + repoURL: + description: RepoURL is the URL to the repository (Git + or Helm) that contains the application manifests + type: string + targetRevision: + description: TargetRevision defines the revision of the + source to sync the application to. In case of Git, this + can be commit, tag, or branch. If omitted, will equal + to HEAD. In case of Helm, this is a semver tag for the + Chart's version. + type: string + required: + - repoURL + type: object + type: array required: - deployedAt - id - - revision type: object type: array observedAt: @@ -1281,6 +2099,14 @@ spec: (Helm) which to sync the application to If omitted, will use the revision specified in app spec. type: string + revisions: + description: Revisions is the list of revision (Git) or + chart version (Helm) which to sync each source in sources + field for the application to If omitted, will use the + revision specified in app spec. + items: + type: string + type: array source: description: Source overrides the source definition set in the application. This is typically set in a Rollback @@ -1539,6 +2365,11 @@ spec: type: object type: array type: object + ref: + description: Ref is reference to another source within + sources field. This field will not be used if used + with a `source` tag. + type: string repoURL: description: RepoURL is the URL to the repository (Git or Helm) that contains the application manifests @@ -1553,6 +2384,291 @@ spec: required: - repoURL type: object + sources: + description: Sources overrides the source definition set + in the application. This is typically set in a Rollback + operation and is nil during a Sync operation + items: + description: ApplicationSource contains all required + information about the source of an application + properties: + chart: + description: Chart is a Helm chart name, and must + be specified for applications sourced from a Helm + repo. + type: string + directory: + description: Directory holds path/directory specific + options + properties: + exclude: + description: Exclude contains a glob pattern + to match paths against that should be explicitly + excluded from being used during manifest generation + type: string + include: + description: Include contains a glob pattern + to match paths against that should be explicitly + included during manifest generation + type: string + jsonnet: + description: Jsonnet holds options specific + to Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet + External Variables + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest + generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level + Arguments + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest + generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan + a directory recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options + properties: + fileParameters: + description: FileParameters are file parameters + to the helm template + items: + description: HelmFileParameter is a file parameter + that's passed to helm template during manifest + generation + properties: + name: + description: Name is the name of the Helm + parameter + type: string + path: + description: Path is the path to the file + containing the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents + helm template from failing when valueFiles + do not exist locally by not appending them + to helm template --values + type: boolean + parameters: + description: Parameters is a list of Helm parameters + which are passed to the helm template command + upon manifest generation + items: + description: HelmParameter is a parameter + that's passed to helm template during manifest + generation + properties: + forceString: + description: ForceString determines whether + to tell Helm to interpret booleans and + numbers as strings + type: boolean + name: + description: Name is the name of the Helm + parameter + type: string + value: + description: Value is the value for the + Helm parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials + to all domains (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release + name to use. If omitted it will use the application + name + type: string + skipCrds: + description: SkipCrds skips custom resource + definition installation step (Helm's --skip-crds) + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value + files to use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to + be passed to helm template, typically defined + as a block + type: string + version: + description: Version is the Helm version to + use for templating ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific + options + properties: + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of + additional annotations to add to rendered + manifests + type: object + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional + labels to add to rendered manifests + type: object + forceCommonAnnotations: + description: ForceCommonAnnotations specifies + whether to force applying common annotations + to resources for Kustomize apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether + to force applying common labels to resources + for Kustomize apps + type: boolean + images: + description: Images is a list of Kustomize image + override specifications + items: + description: KustomizeImage represents a Kustomize + image definition in the format [old_image_name=]: + type: string + type: array + namePrefix: + description: NamePrefix is a prefix appended + to resources for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended + to resources for Kustomize apps + type: string + version: + description: Version controls which version + of Kustomize to use for rendering manifests + type: string + type: object + path: + description: Path is a directory path within the + Git repository, and is only valid for applications + sourced from Git. + type: string + plugin: + description: Plugin holds config management plugin + specific options + properties: + env: + description: Env is a list of environment variable + entries + items: + description: EnvEntry represents an entry + in the application's environment + properties: + name: + description: Name is the name of the variable, + usually expressed in uppercase + type: string + value: + description: Value is the value of the + variable + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + description: Array is the value of an + array type parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map + type parameter. + type: object + name: + description: Name is the name identifying + a parameter. + type: string + string: + description: String_ is the value of a + string type parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source + within sources field. This field will not be used + if used with a `source` tag. + type: string + repoURL: + description: RepoURL is the URL to the repository + (Git or Helm) that contains the application manifests + type: string + targetRevision: + description: TargetRevision defines the revision + of the source to sync the application to. In case + of Git, this can be commit, tag, or branch. If + omitted, will equal to HEAD. In case of Helm, + this is a semver tag for the Chart's version. + type: string + required: + - repoURL + type: object + type: array syncOptions: description: SyncOptions provide per-sync sync-options, e.g. Validate=false @@ -1662,6 +2778,12 @@ spec: description: Revision holds the revision this sync operation was performed to type: string + revisions: + description: Revisions holds the revision this sync operation + was performed for respective indexed source in sources field + items: + type: string + type: array source: description: Source records the application source information of the sync, used for comparing auto-sync @@ -1908,6 +3030,11 @@ spec: type: object type: array type: object + ref: + description: Ref is reference to another source within + sources field. This field will not be used if used with + a `source` tag. + type: string repoURL: description: RepoURL is the URL to the repository (Git or Helm) that contains the application manifests @@ -1922,6 +3049,284 @@ spec: required: - repoURL type: object + sources: + description: Source records the application source information + of the sync, used for comparing auto-sync + items: + description: ApplicationSource contains all required information + about the source of an application + properties: + chart: + description: Chart is a Helm chart name, and must be + specified for applications sourced from a Helm repo. + type: string + directory: + description: Directory holds path/directory specific + options + properties: + exclude: + description: Exclude contains a glob pattern to + match paths against that should be explicitly + excluded from being used during manifest generation + type: string + include: + description: Include contains a glob pattern to + match paths against that should be explicitly + included during manifest generation + type: string + jsonnet: + description: Jsonnet holds options specific to Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet External + Variables + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest + generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level + Arguments + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest + generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan a + directory recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options + properties: + fileParameters: + description: FileParameters are file parameters + to the helm template + items: + description: HelmFileParameter is a file parameter + that's passed to helm template during manifest + generation + properties: + name: + description: Name is the name of the Helm + parameter + type: string + path: + description: Path is the path to the file + containing the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents helm + template from failing when valueFiles do not exist + locally by not appending them to helm template + --values + type: boolean + parameters: + description: Parameters is a list of Helm parameters + which are passed to the helm template command + upon manifest generation + items: + description: HelmParameter is a parameter that's + passed to helm template during manifest generation + properties: + forceString: + description: ForceString determines whether + to tell Helm to interpret booleans and numbers + as strings + type: boolean + name: + description: Name is the name of the Helm + parameter + type: string + value: + description: Value is the value for the Helm + parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials to + all domains (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release name + to use. If omitted it will use the application + name + type: string + skipCrds: + description: SkipCrds skips custom resource definition + installation step (Helm's --skip-crds) + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value + files to use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to be + passed to helm template, typically defined as + a block + type: string + version: + description: Version is the Helm version to use + for templating ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific options + properties: + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of additional + annotations to add to rendered manifests + type: object + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional + labels to add to rendered manifests + type: object + forceCommonAnnotations: + description: ForceCommonAnnotations specifies whether + to force applying common annotations to resources + for Kustomize apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether + to force applying common labels to resources for + Kustomize apps + type: boolean + images: + description: Images is a list of Kustomize image + override specifications + items: + description: KustomizeImage represents a Kustomize + image definition in the format [old_image_name=]: + type: string + type: array + namePrefix: + description: NamePrefix is a prefix appended to + resources for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended to + resources for Kustomize apps + type: string + version: + description: Version controls which version of Kustomize + to use for rendering manifests + type: string + type: object + path: + description: Path is a directory path within the Git + repository, and is only valid for applications sourced + from Git. + type: string + plugin: + description: Plugin holds config management plugin specific + options + properties: + env: + description: Env is a list of environment variable + entries + items: + description: EnvEntry represents an entry in the + application's environment + properties: + name: + description: Name is the name of the variable, + usually expressed in uppercase + type: string + value: + description: Value is the value of the variable + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + description: Array is the value of an array + type parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map type + parameter. + type: object + name: + description: Name is the name identifying + a parameter. + type: string + string: + description: String_ is the value of a string + type parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source within + sources field. This field will not be used if used + with a `source` tag. + type: string + repoURL: + description: RepoURL is the URL to the repository (Git + or Helm) that contains the application manifests + type: string + targetRevision: + description: TargetRevision defines the revision of + the source to sync the application to. In case of + Git, this can be commit, tag, or branch. If omitted, + will equal to HEAD. In case of Helm, this is a semver + tag for the Chart's version. + type: string + required: + - repoURL + type: object + type: array required: - revision type: object @@ -1985,6 +3390,14 @@ spec: sourceType: description: SourceType specifies the type of this application type: string + sourceTypes: + description: SourceTypes specifies the type of the sources included + in the application + items: + description: ApplicationSourceType specifies the type of the application's + source + type: string + type: array summary: description: Summary contains a list of URLs and container images used by this application @@ -2274,6 +3687,11 @@ spec: type: object type: array type: object + ref: + description: Ref is reference to another source within + sources field. This field will not be used if used with + a `source` tag. + type: string repoURL: description: RepoURL is the URL to the repository (Git or Helm) that contains the application manifests @@ -2288,14 +3706,297 @@ spec: required: - repoURL type: object + sources: + description: Sources is a reference to the application's multiple + sources used for comparison + items: + description: ApplicationSource contains all required information + about the source of an application + properties: + chart: + description: Chart is a Helm chart name, and must be + specified for applications sourced from a Helm repo. + type: string + directory: + description: Directory holds path/directory specific + options + properties: + exclude: + description: Exclude contains a glob pattern to + match paths against that should be explicitly + excluded from being used during manifest generation + type: string + include: + description: Include contains a glob pattern to + match paths against that should be explicitly + included during manifest generation + type: string + jsonnet: + description: Jsonnet holds options specific to Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet External + Variables + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest + generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level + Arguments + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest + generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan a + directory recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options + properties: + fileParameters: + description: FileParameters are file parameters + to the helm template + items: + description: HelmFileParameter is a file parameter + that's passed to helm template during manifest + generation + properties: + name: + description: Name is the name of the Helm + parameter + type: string + path: + description: Path is the path to the file + containing the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents helm + template from failing when valueFiles do not exist + locally by not appending them to helm template + --values + type: boolean + parameters: + description: Parameters is a list of Helm parameters + which are passed to the helm template command + upon manifest generation + items: + description: HelmParameter is a parameter that's + passed to helm template during manifest generation + properties: + forceString: + description: ForceString determines whether + to tell Helm to interpret booleans and numbers + as strings + type: boolean + name: + description: Name is the name of the Helm + parameter + type: string + value: + description: Value is the value for the Helm + parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials to + all domains (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release name + to use. If omitted it will use the application + name + type: string + skipCrds: + description: SkipCrds skips custom resource definition + installation step (Helm's --skip-crds) + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value + files to use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to be + passed to helm template, typically defined as + a block + type: string + version: + description: Version is the Helm version to use + for templating ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific options + properties: + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of additional + annotations to add to rendered manifests + type: object + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional + labels to add to rendered manifests + type: object + forceCommonAnnotations: + description: ForceCommonAnnotations specifies whether + to force applying common annotations to resources + for Kustomize apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether + to force applying common labels to resources for + Kustomize apps + type: boolean + images: + description: Images is a list of Kustomize image + override specifications + items: + description: KustomizeImage represents a Kustomize + image definition in the format [old_image_name=]: + type: string + type: array + namePrefix: + description: NamePrefix is a prefix appended to + resources for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended to + resources for Kustomize apps + type: string + version: + description: Version controls which version of Kustomize + to use for rendering manifests + type: string + type: object + path: + description: Path is a directory path within the Git + repository, and is only valid for applications sourced + from Git. + type: string + plugin: + description: Plugin holds config management plugin specific + options + properties: + env: + description: Env is a list of environment variable + entries + items: + description: EnvEntry represents an entry in the + application's environment + properties: + name: + description: Name is the name of the variable, + usually expressed in uppercase + type: string + value: + description: Value is the value of the variable + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + description: Array is the value of an array + type parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map type + parameter. + type: object + name: + description: Name is the name identifying + a parameter. + type: string + string: + description: String_ is the value of a string + type parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source within + sources field. This field will not be used if used + with a `source` tag. + type: string + repoURL: + description: RepoURL is the URL to the repository (Git + or Helm) that contains the application manifests + type: string + targetRevision: + description: TargetRevision defines the revision of + the source to sync the application to. In case of + Git, this can be commit, tag, or branch. If omitted, + will equal to HEAD. In case of Helm, this is a semver + tag for the Chart's version. + type: string + required: + - repoURL + type: object + type: array required: - destination - - source type: object revision: description: Revision contains information about the revision the comparison has been performed to type: string + revisions: + description: Revisions contains information about the revisions + of multiple sources the comparison has been performed to + items: + type: string + type: array status: description: Status is the sync state of the comparison type: string @@ -2601,6 +4302,8 @@ spec: type: object type: array type: object + ref: + type: string repoURL: type: string targetRevision: @@ -2608,6 +4311,165 @@ spec: required: - repoURL type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array syncPolicy: properties: automated: @@ -2654,7 +4516,6 @@ spec: required: - destination - project - - source type: object required: - metadata @@ -2916,6 +4777,8 @@ spec: type: object type: array type: object + ref: + type: string repoURL: type: string targetRevision: @@ -2923,6 +4786,165 @@ spec: required: - repoURL type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array syncPolicy: properties: automated: @@ -2969,7 +4991,6 @@ spec: required: - destination - project - - source type: object required: - metadata @@ -3214,34 +5235,195 @@ spec: - name - value type: object - type: array - name: - type: string - parameters: - items: - properties: - array: - items: + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: type: string - type: array - map: - additionalProperties: + value: type: string - type: object - name: - type: string - string: - type: string - type: object - type: array - type: object - repoURL: - type: string - targetRevision: - type: string - required: - - repoURL - type: object + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array syncPolicy: properties: automated: @@ -3288,7 +5470,6 @@ spec: required: - destination - project - - source type: object required: - metadata @@ -3529,6 +5710,8 @@ spec: type: object type: array type: object + ref: + type: string repoURL: type: string targetRevision: @@ -3536,6 +5719,165 @@ spec: required: - repoURL type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array syncPolicy: properties: automated: @@ -3582,7 +5924,6 @@ spec: required: - destination - project - - source type: object required: - metadata @@ -3852,6 +6193,8 @@ spec: type: object type: array type: object + ref: + type: string repoURL: type: string targetRevision: @@ -3859,6 +6202,165 @@ spec: required: - repoURL type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array syncPolicy: properties: automated: @@ -3905,7 +6407,6 @@ spec: required: - destination - project - - source type: object required: - metadata @@ -4155,25 +6656,186 @@ spec: array: items: type: string - type: array - map: - additionalProperties: + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: type: string - type: object - name: - type: string - string: - type: string - type: object - type: array - type: object - repoURL: - type: string - targetRevision: - type: string - required: - - repoURL - type: object + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array syncPolicy: properties: automated: @@ -4220,7 +6882,6 @@ spec: required: - destination - project - - source type: object required: - metadata @@ -4486,6 +7147,8 @@ spec: type: object type: array type: object + ref: + type: string repoURL: type: string targetRevision: @@ -4493,6 +7156,165 @@ spec: required: - repoURL type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array syncPolicy: properties: automated: @@ -4539,7 +7361,6 @@ spec: required: - destination - project - - source type: object required: - metadata @@ -4780,6 +7601,8 @@ spec: type: object type: array type: object + ref: + type: string repoURL: type: string targetRevision: @@ -4787,6 +7610,165 @@ spec: required: - repoURL type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array syncPolicy: properties: automated: @@ -4833,7 +7815,6 @@ spec: required: - destination - project - - source type: object required: - metadata @@ -5191,6 +8172,8 @@ spec: type: object type: array type: object + ref: + type: string repoURL: type: string targetRevision: @@ -5198,6 +8181,165 @@ spec: required: - repoURL type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array syncPolicy: properties: automated: @@ -5244,7 +8386,6 @@ spec: required: - destination - project - - source type: object required: - metadata @@ -5649,6 +8790,8 @@ spec: type: object type: array type: object + ref: + type: string repoURL: type: string targetRevision: @@ -5656,6 +8799,165 @@ spec: required: - repoURL type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array syncPolicy: properties: automated: @@ -5702,7 +9004,6 @@ spec: required: - destination - project - - source type: object required: - metadata @@ -5946,25 +9247,186 @@ spec: array: items: type: string - type: array - map: - additionalProperties: + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: type: string - type: object - name: - type: string - string: - type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string type: object - type: array - type: object - repoURL: - type: string - targetRevision: - type: string - required: - - repoURL - type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array syncPolicy: properties: automated: @@ -6011,7 +9473,6 @@ spec: required: - destination - project - - source type: object required: - metadata @@ -6281,6 +9742,8 @@ spec: type: object type: array type: object + ref: + type: string repoURL: type: string targetRevision: @@ -6288,6 +9751,165 @@ spec: required: - repoURL type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array syncPolicy: properties: automated: @@ -6334,7 +9956,6 @@ spec: required: - destination - project - - source type: object required: - metadata @@ -6596,6 +10217,8 @@ spec: type: object type: array type: object + ref: + type: string repoURL: type: string targetRevision: @@ -6603,6 +10226,165 @@ spec: required: - repoURL type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array syncPolicy: properties: automated: @@ -6649,7 +10431,6 @@ spec: required: - destination - project - - source type: object required: - metadata @@ -6915,6 +10696,8 @@ spec: type: object type: array type: object + ref: + type: string repoURL: type: string targetRevision: @@ -6922,6 +10705,165 @@ spec: required: - repoURL type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array syncPolicy: properties: automated: @@ -6968,7 +10910,6 @@ spec: required: - destination - project - - source type: object required: - metadata @@ -7209,6 +11150,8 @@ spec: type: object type: array type: object + ref: + type: string repoURL: type: string targetRevision: @@ -7216,6 +11159,165 @@ spec: required: - repoURL type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array syncPolicy: properties: automated: @@ -7262,7 +11364,6 @@ spec: required: - destination - project - - source type: object required: - metadata @@ -7620,6 +11721,8 @@ spec: type: object type: array type: object + ref: + type: string repoURL: type: string targetRevision: @@ -7627,6 +11730,165 @@ spec: required: - repoURL type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array syncPolicy: properties: automated: @@ -7673,7 +11935,6 @@ spec: required: - destination - project - - source type: object required: - metadata @@ -8078,6 +12339,8 @@ spec: type: object type: array type: object + ref: + type: string repoURL: type: string targetRevision: @@ -8085,6 +12348,165 @@ spec: required: - repoURL type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array syncPolicy: properties: automated: @@ -8131,7 +12553,6 @@ spec: required: - destination - project - - source type: object required: - metadata @@ -8391,6 +12812,8 @@ spec: type: object type: array type: object + ref: + type: string repoURL: type: string targetRevision: @@ -8398,6 +12821,165 @@ spec: required: - repoURL type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array syncPolicy: properties: automated: @@ -8444,7 +13026,6 @@ spec: required: - destination - project - - source type: object required: - metadata @@ -8787,25 +13368,186 @@ spec: array: items: type: string - type: array - map: - additionalProperties: + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: type: string - type: object - name: - type: string - string: - type: string - type: object - type: array - type: object - repoURL: - type: string - targetRevision: - type: string - required: - - repoURL - type: object + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array syncPolicy: properties: automated: @@ -8852,7 +13594,6 @@ spec: required: - destination - project - - source type: object required: - metadata @@ -9257,6 +13998,8 @@ spec: type: object type: array type: object + ref: + type: string repoURL: type: string targetRevision: @@ -9264,6 +14007,165 @@ spec: required: - repoURL type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array syncPolicy: properties: automated: @@ -9310,7 +14212,6 @@ spec: required: - destination - project - - source type: object required: - metadata @@ -9573,6 +14474,8 @@ spec: type: object type: array type: object + ref: + type: string repoURL: type: string targetRevision: @@ -9580,6 +14483,165 @@ spec: required: - repoURL type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array syncPolicy: properties: automated: @@ -9626,7 +14688,6 @@ spec: required: - destination - project - - source type: object required: - metadata diff --git a/manifests/install.yaml b/manifests/install.yaml index 192ad144a8ffd..9f25ea32518df 100644 --- a/manifests/install.yaml +++ b/manifests/install.yaml @@ -144,6 +144,14 @@ spec: which to sync the application to If omitted, will use the revision specified in app spec. type: string + revisions: + description: Revisions is the list of revision (Git) or chart + version (Helm) which to sync each source in sources field for + the application to If omitted, will use the revision specified + in app spec. + items: + type: string + type: array source: description: Source overrides the source definition set in the application. This is typically set in a Rollback operation and @@ -383,6 +391,11 @@ spec: type: object type: array type: object + ref: + description: Ref is reference to another source within sources + field. This field will not be used if used with a `source` + tag. + type: string repoURL: description: RepoURL is the URL to the repository (Git or Helm) that contains the application manifests @@ -396,510 +409,1042 @@ spec: required: - repoURL type: object - syncOptions: - description: SyncOptions provide per-sync sync-options, e.g. Validate=false + sources: + description: Sources overrides the source definition set in the + application. This is typically set in a Rollback operation and + is nil during a Sync operation items: - type: string - type: array - syncStrategy: - description: SyncStrategy describes how to perform the sync - properties: - apply: - description: Apply will perform a `kubectl apply` to perform - the sync. - properties: - force: - description: Force indicates whether or not to supply - the --force flag to `kubectl apply`. The --force flag - deletes and re-create the resource, when PATCH encounters - conflict and has retried for 5 times. - type: boolean - type: object - hook: - description: Hook will submit any referenced resources to - perform the sync. This is the default strategy - properties: - force: - description: Force indicates whether or not to supply - the --force flag to `kubectl apply`. The --force flag - deletes and re-create the resource, when PATCH encounters - conflict and has retried for 5 times. - type: boolean - type: object - type: object - type: object - type: object - spec: - description: ApplicationSpec represents desired application state. Contains - link to repository with application definition and additional parameters - link definition revision. - properties: - destination: - description: Destination is a reference to the target Kubernetes server - and namespace - properties: - name: - description: Name is an alternate way of specifying the target - cluster by its symbolic name - type: string - namespace: - description: Namespace specifies the target namespace for the - application's resources. The namespace will only be set for - namespace-scoped resources that have not set a value for .metadata.namespace - type: string - server: - description: Server specifies the URL of the target cluster and - must be set to the Kubernetes control plane API - type: string - type: object - ignoreDifferences: - description: IgnoreDifferences is a list of resources and their fields - which should be ignored during comparison - items: - description: ResourceIgnoreDifferences contains resource filter - and list of json paths which should be ignored during comparison - with live state. - properties: - group: - type: string - jqPathExpressions: - items: - type: string - type: array - jsonPointers: - items: - type: string - type: array - kind: - type: string - managedFieldsManagers: - description: ManagedFieldsManagers is a list of trusted managers. - Fields mutated by those managers will take precedence over - the desired state defined in the SCM and won't be displayed - in diffs - items: - type: string - type: array - name: - type: string - namespace: - type: string - required: - - kind - type: object - type: array - info: - description: Info contains a list of information (URLs, email addresses, - and plain text) that relates to the application - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - project: - description: Project is a reference to the project this application - belongs to. The empty string means that application belongs to the - 'default' project. - type: string - revisionHistoryLimit: - description: RevisionHistoryLimit limits the number of items kept - in the application's revision history, which is used for informational - purposes as well as for rollbacks to previous versions. This should - only be changed in exceptional circumstances. Setting to zero will - store no history. This will reduce storage used. Increasing will - increase the space used to store the history, so we do not recommend - increasing it. Default is 10. - format: int64 - type: integer - source: - description: Source is a reference to the location of the application's - manifests or chart - properties: - chart: - description: Chart is a Helm chart name, and must be specified - for applications sourced from a Helm repo. - type: string - directory: - description: Directory holds path/directory specific options - properties: - exclude: - description: Exclude contains a glob pattern to match paths - against that should be explicitly excluded from being used - during manifest generation - type: string - include: - description: Include contains a glob pattern to match paths - against that should be explicitly included during manifest - generation - type: string - jsonnet: - description: Jsonnet holds options specific to Jsonnet - properties: - extVars: - description: ExtVars is a list of Jsonnet External Variables - items: - description: JsonnetVar represents a variable to be - passed to jsonnet during manifest generation - properties: - code: - type: boolean - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - libs: - description: Additional library search dirs - items: - type: string - type: array - tlas: - description: TLAS is a list of Jsonnet Top-level Arguments - items: - description: JsonnetVar represents a variable to be - passed to jsonnet during manifest generation - properties: - code: - type: boolean - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - type: object - recurse: - description: Recurse specifies whether to scan a directory - recursively for manifests - type: boolean - type: object - helm: - description: Helm holds helm specific options - properties: - fileParameters: - description: FileParameters are file parameters to the helm - template - items: - description: HelmFileParameter is a file parameter that's - passed to helm template during manifest generation - properties: - name: - description: Name is the name of the Helm parameter - type: string - path: - description: Path is the path to the file containing - the values for the Helm parameter - type: string - type: object - type: array - ignoreMissingValueFiles: - description: IgnoreMissingValueFiles prevents helm template - from failing when valueFiles do not exist locally by not - appending them to helm template --values - type: boolean - parameters: - description: Parameters is a list of Helm parameters which - are passed to the helm template command upon manifest generation - items: - description: HelmParameter is a parameter that's passed - to helm template during manifest generation + description: ApplicationSource contains all required information + about the source of an application + properties: + chart: + description: Chart is a Helm chart name, and must be specified + for applications sourced from a Helm repo. + type: string + directory: + description: Directory holds path/directory specific options properties: - forceString: - description: ForceString determines whether to tell - Helm to interpret booleans and numbers as strings - type: boolean - name: - description: Name is the name of the Helm parameter + exclude: + description: Exclude contains a glob pattern to match + paths against that should be explicitly excluded from + being used during manifest generation type: string - value: - description: Value is the value for the Helm parameter + include: + description: Include contains a glob pattern to match + paths against that should be explicitly included during + manifest generation type: string - type: object - type: array - passCredentials: - description: PassCredentials pass credentials to all domains - (Helm's --pass-credentials) - type: boolean - releaseName: - description: ReleaseName is the Helm release name to use. - If omitted it will use the application name - type: string - skipCrds: - description: SkipCrds skips custom resource definition installation - step (Helm's --skip-crds) - type: boolean - valueFiles: - description: ValuesFiles is a list of Helm value files to - use when generating a template - items: - type: string - type: array - values: - description: Values specifies Helm values to be passed to - helm template, typically defined as a block - type: string - version: - description: Version is the Helm version to use for templating - ("3") - type: string - type: object - kustomize: - description: Kustomize holds kustomize specific options - properties: - commonAnnotations: - additionalProperties: - type: string - description: CommonAnnotations is a list of additional annotations - to add to rendered manifests - type: object - commonLabels: - additionalProperties: - type: string - description: CommonLabels is a list of additional labels to - add to rendered manifests - type: object - forceCommonAnnotations: - description: ForceCommonAnnotations specifies whether to force - applying common annotations to resources for Kustomize apps - type: boolean - forceCommonLabels: - description: ForceCommonLabels specifies whether to force - applying common labels to resources for Kustomize apps - type: boolean - images: - description: Images is a list of Kustomize image override - specifications - items: - description: KustomizeImage represents a Kustomize image - definition in the format [old_image_name=]: - type: string - type: array - namePrefix: - description: NamePrefix is a prefix appended to resources - for Kustomize apps - type: string - nameSuffix: - description: NameSuffix is a suffix appended to resources - for Kustomize apps - type: string - version: - description: Version controls which version of Kustomize to - use for rendering manifests - type: string - type: object - path: - description: Path is a directory path within the Git repository, - and is only valid for applications sourced from Git. - type: string - plugin: - description: Plugin holds config management plugin specific options - properties: - env: - description: Env is a list of environment variable entries - items: - description: EnvEntry represents an entry in the application's - environment + jsonnet: + description: Jsonnet holds options specific to Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet External + Variables + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level + Arguments + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan a directory + recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options properties: - name: - description: Name is the name of the variable, usually - expressed in uppercase + fileParameters: + description: FileParameters are file parameters to the + helm template + items: + description: HelmFileParameter is a file parameter + that's passed to helm template during manifest generation + properties: + name: + description: Name is the name of the Helm parameter + type: string + path: + description: Path is the path to the file containing + the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents helm template + from failing when valueFiles do not exist locally + by not appending them to helm template --values + type: boolean + parameters: + description: Parameters is a list of Helm parameters + which are passed to the helm template command upon + manifest generation + items: + description: HelmParameter is a parameter that's passed + to helm template during manifest generation + properties: + forceString: + description: ForceString determines whether to + tell Helm to interpret booleans and numbers + as strings + type: boolean + name: + description: Name is the name of the Helm parameter + type: string + value: + description: Value is the value for the Helm parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials to all + domains (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release name to + use. If omitted it will use the application name type: string - value: - description: Value is the value of the variable + skipCrds: + description: SkipCrds skips custom resource definition + installation step (Helm's --skip-crds) + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value files + to use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to be passed + to helm template, typically defined as a block + type: string + version: + description: Version is the Helm version to use for + templating ("3") type: string - required: - - name - - value type: object - type: array - name: - type: string - parameters: - items: + kustomize: + description: Kustomize holds kustomize specific options properties: - array: - description: Array is the value of an array type parameter. - items: + commonAnnotations: + additionalProperties: type: string - type: array - map: + description: CommonAnnotations is a list of additional + annotations to add to rendered manifests + type: object + commonLabels: additionalProperties: type: string - description: Map is the value of a map type parameter. + description: CommonLabels is a list of additional labels + to add to rendered manifests type: object - name: - description: Name is the name identifying a parameter. + forceCommonAnnotations: + description: ForceCommonAnnotations specifies whether + to force applying common annotations to resources + for Kustomize apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether to + force applying common labels to resources for Kustomize + apps + type: boolean + images: + description: Images is a list of Kustomize image override + specifications + items: + description: KustomizeImage represents a Kustomize + image definition in the format [old_image_name=]: + type: string + type: array + namePrefix: + description: NamePrefix is a prefix appended to resources + for Kustomize apps type: string - string: - description: String_ is the value of a string type parameter. + nameSuffix: + description: NameSuffix is a suffix appended to resources + for Kustomize apps + type: string + version: + description: Version controls which version of Kustomize + to use for rendering manifests type: string type: object - type: array - type: object - repoURL: - description: RepoURL is the URL to the repository (Git or Helm) - that contains the application manifests - type: string - targetRevision: - description: TargetRevision defines the revision of the source - to sync the application to. In case of Git, this can be commit, - tag, or branch. If omitted, will equal to HEAD. In case of Helm, - this is a semver tag for the Chart's version. - type: string - required: - - repoURL - type: object - syncPolicy: - description: SyncPolicy controls when and how a sync will be performed - properties: - automated: - description: Automated will keep an application synced to the - target revision - properties: - allowEmpty: - description: 'AllowEmpty allows apps have zero live resources - (default: false)' - type: boolean - prune: - description: 'Prune specifies whether to delete resources - from the cluster that are not found in the sources anymore - as part of automated sync (default: false)' - type: boolean - selfHeal: - description: 'SelfHeal specifes whether to revert resources - back to their desired state upon modification in the cluster - (default: false)' - type: boolean - type: object - managedNamespaceMetadata: - description: ManagedNamespaceMetadata controls metadata in the - given namespace (if CreateNamespace=true) - properties: - annotations: - additionalProperties: + path: + description: Path is a directory path within the Git repository, + and is only valid for applications sourced from Git. type: string - type: object - labels: - additionalProperties: + plugin: + description: Plugin holds config management plugin specific + options + properties: + env: + description: Env is a list of environment variable entries + items: + description: EnvEntry represents an entry in the application's + environment + properties: + name: + description: Name is the name of the variable, + usually expressed in uppercase + type: string + value: + description: Value is the value of the variable + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + description: Array is the value of an array type + parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map type parameter. + type: object + name: + description: Name is the name identifying a parameter. + type: string + string: + description: String_ is the value of a string + type parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source within sources + field. This field will not be used if used with a `source` + tag. type: string - type: object - type: object - retry: - description: Retry controls failed sync retry behavior - properties: - backoff: - description: Backoff controls how to backoff on subsequent - retries of failed syncs - properties: - duration: - description: Duration is the amount to back off. Default - unit is seconds, but could also be a duration (e.g. - "2m", "1h") - type: string - factor: - description: Factor is a factor to multiply the base duration - after each failed retry - format: int64 - type: integer - maxDuration: - description: MaxDuration is the maximum amount of time - allowed for the backoff strategy - type: string - type: object - limit: - description: Limit is the maximum number of attempts for retrying - a failed sync. If set to 0, no retries will be performed. - format: int64 - type: integer - type: object + repoURL: + description: RepoURL is the URL to the repository (Git or + Helm) that contains the application manifests + type: string + targetRevision: + description: TargetRevision defines the revision of the + source to sync the application to. In case of Git, this + can be commit, tag, or branch. If omitted, will equal + to HEAD. In case of Helm, this is a semver tag for the + Chart's version. + type: string + required: + - repoURL + type: object + type: array syncOptions: - description: Options allow you to specify whole app sync-options + description: SyncOptions provide per-sync sync-options, e.g. Validate=false items: type: string type: array + syncStrategy: + description: SyncStrategy describes how to perform the sync + properties: + apply: + description: Apply will perform a `kubectl apply` to perform + the sync. + properties: + force: + description: Force indicates whether or not to supply + the --force flag to `kubectl apply`. The --force flag + deletes and re-create the resource, when PATCH encounters + conflict and has retried for 5 times. + type: boolean + type: object + hook: + description: Hook will submit any referenced resources to + perform the sync. This is the default strategy + properties: + force: + description: Force indicates whether or not to supply + the --force flag to `kubectl apply`. The --force flag + deletes and re-create the resource, when PATCH encounters + conflict and has retried for 5 times. + type: boolean + type: object + type: object type: object - required: - - destination - - project - - source type: object - status: - description: ApplicationStatus contains status information for the application + spec: + description: ApplicationSpec represents desired application state. Contains + link to repository with application definition and additional parameters + link definition revision. properties: - conditions: - description: Conditions is a list of currently observed application - conditions - items: - description: ApplicationCondition contains details about an application - condition, which is usally an error or warning - properties: - lastTransitionTime: - description: LastTransitionTime is the time the condition was - last observed - format: date-time - type: string - message: - description: Message contains human-readable message indicating - details about condition - type: string - type: - description: Type is an application condition type - type: string - required: - - message - - type - type: object - type: array - health: - description: Health contains information about the application's current - health status + destination: + description: Destination is a reference to the target Kubernetes server + and namespace properties: - message: - description: Message is a human-readable informational message - describing the health status + name: + description: Name is an alternate way of specifying the target + cluster by its symbolic name type: string - status: - description: Status holds the status code of the application or - resource + namespace: + description: Namespace specifies the target namespace for the + application's resources. The namespace will only be set for + namespace-scoped resources that have not set a value for .metadata.namespace + type: string + server: + description: Server specifies the URL of the target cluster and + must be set to the Kubernetes control plane API type: string type: object - history: - description: History contains information about the application's - sync history + ignoreDifferences: + description: IgnoreDifferences is a list of resources and their fields + which should be ignored during comparison items: - description: RevisionHistory contains history information about - a previous sync + description: ResourceIgnoreDifferences contains resource filter + and list of json paths which should be ignored during comparison + with live state. properties: - deployStartedAt: - description: DeployStartedAt holds the time the sync operation - started - format: date-time + group: type: string - deployedAt: - description: DeployedAt holds the time the sync operation completed - format: date-time + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: type: string - id: - description: ID is an auto incrementing identifier of the RevisionHistory + managedFieldsManagers: + description: ManagedFieldsManagers is a list of trusted managers. + Fields mutated by those managers will take precedence over + the desired state defined in the SCM and won't be displayed + in diffs + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + description: Info contains a list of information (URLs, email addresses, + and plain text) that relates to the application + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + description: Project is a reference to the project this application + belongs to. The empty string means that application belongs to the + 'default' project. + type: string + revisionHistoryLimit: + description: RevisionHistoryLimit limits the number of items kept + in the application's revision history, which is used for informational + purposes as well as for rollbacks to previous versions. This should + only be changed in exceptional circumstances. Setting to zero will + store no history. This will reduce storage used. Increasing will + increase the space used to store the history, so we do not recommend + increasing it. Default is 10. + format: int64 + type: integer + source: + description: Source is a reference to the location of the application's + manifests or chart + properties: + chart: + description: Chart is a Helm chart name, and must be specified + for applications sourced from a Helm repo. + type: string + directory: + description: Directory holds path/directory specific options + properties: + exclude: + description: Exclude contains a glob pattern to match paths + against that should be explicitly excluded from being used + during manifest generation + type: string + include: + description: Include contains a glob pattern to match paths + against that should be explicitly included during manifest + generation + type: string + jsonnet: + description: Jsonnet holds options specific to Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet External Variables + items: + description: JsonnetVar represents a variable to be + passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level Arguments + items: + description: JsonnetVar represents a variable to be + passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan a directory + recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options + properties: + fileParameters: + description: FileParameters are file parameters to the helm + template + items: + description: HelmFileParameter is a file parameter that's + passed to helm template during manifest generation + properties: + name: + description: Name is the name of the Helm parameter + type: string + path: + description: Path is the path to the file containing + the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents helm template + from failing when valueFiles do not exist locally by not + appending them to helm template --values + type: boolean + parameters: + description: Parameters is a list of Helm parameters which + are passed to the helm template command upon manifest generation + items: + description: HelmParameter is a parameter that's passed + to helm template during manifest generation + properties: + forceString: + description: ForceString determines whether to tell + Helm to interpret booleans and numbers as strings + type: boolean + name: + description: Name is the name of the Helm parameter + type: string + value: + description: Value is the value for the Helm parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials to all domains + (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release name to use. + If omitted it will use the application name + type: string + skipCrds: + description: SkipCrds skips custom resource definition installation + step (Helm's --skip-crds) + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value files to + use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to be passed to + helm template, typically defined as a block + type: string + version: + description: Version is the Helm version to use for templating + ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific options + properties: + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of additional annotations + to add to rendered manifests + type: object + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional labels to + add to rendered manifests + type: object + forceCommonAnnotations: + description: ForceCommonAnnotations specifies whether to force + applying common annotations to resources for Kustomize apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether to force + applying common labels to resources for Kustomize apps + type: boolean + images: + description: Images is a list of Kustomize image override + specifications + items: + description: KustomizeImage represents a Kustomize image + definition in the format [old_image_name=]: + type: string + type: array + namePrefix: + description: NamePrefix is a prefix appended to resources + for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended to resources + for Kustomize apps + type: string + version: + description: Version controls which version of Kustomize to + use for rendering manifests + type: string + type: object + path: + description: Path is a directory path within the Git repository, + and is only valid for applications sourced from Git. + type: string + plugin: + description: Plugin holds config management plugin specific options + properties: + env: + description: Env is a list of environment variable entries + items: + description: EnvEntry represents an entry in the application's + environment + properties: + name: + description: Name is the name of the variable, usually + expressed in uppercase + type: string + value: + description: Value is the value of the variable + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + description: Array is the value of an array type parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map type parameter. + type: object + name: + description: Name is the name identifying a parameter. + type: string + string: + description: String_ is the value of a string type parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source within sources + field. This field will not be used if used with a `source` tag. + type: string + repoURL: + description: RepoURL is the URL to the repository (Git or Helm) + that contains the application manifests + type: string + targetRevision: + description: TargetRevision defines the revision of the source + to sync the application to. In case of Git, this can be commit, + tag, or branch. If omitted, will equal to HEAD. In case of Helm, + this is a semver tag for the Chart's version. + type: string + required: + - repoURL + type: object + sources: + description: Sources is a reference to the location of the application's + manifests or chart + items: + description: ApplicationSource contains all required information + about the source of an application + properties: + chart: + description: Chart is a Helm chart name, and must be specified + for applications sourced from a Helm repo. + type: string + directory: + description: Directory holds path/directory specific options + properties: + exclude: + description: Exclude contains a glob pattern to match paths + against that should be explicitly excluded from being + used during manifest generation + type: string + include: + description: Include contains a glob pattern to match paths + against that should be explicitly included during manifest + generation + type: string + jsonnet: + description: Jsonnet holds options specific to Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet External Variables + items: + description: JsonnetVar represents a variable to be + passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level Arguments + items: + description: JsonnetVar represents a variable to be + passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan a directory + recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options + properties: + fileParameters: + description: FileParameters are file parameters to the helm + template + items: + description: HelmFileParameter is a file parameter that's + passed to helm template during manifest generation + properties: + name: + description: Name is the name of the Helm parameter + type: string + path: + description: Path is the path to the file containing + the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents helm template + from failing when valueFiles do not exist locally by not + appending them to helm template --values + type: boolean + parameters: + description: Parameters is a list of Helm parameters which + are passed to the helm template command upon manifest + generation + items: + description: HelmParameter is a parameter that's passed + to helm template during manifest generation + properties: + forceString: + description: ForceString determines whether to tell + Helm to interpret booleans and numbers as strings + type: boolean + name: + description: Name is the name of the Helm parameter + type: string + value: + description: Value is the value for the Helm parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials to all domains + (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release name to use. + If omitted it will use the application name + type: string + skipCrds: + description: SkipCrds skips custom resource definition installation + step (Helm's --skip-crds) + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value files to + use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to be passed to + helm template, typically defined as a block + type: string + version: + description: Version is the Helm version to use for templating + ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific options + properties: + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of additional annotations + to add to rendered manifests + type: object + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional labels + to add to rendered manifests + type: object + forceCommonAnnotations: + description: ForceCommonAnnotations specifies whether to + force applying common annotations to resources for Kustomize + apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether to force + applying common labels to resources for Kustomize apps + type: boolean + images: + description: Images is a list of Kustomize image override + specifications + items: + description: KustomizeImage represents a Kustomize image + definition in the format [old_image_name=]: + type: string + type: array + namePrefix: + description: NamePrefix is a prefix appended to resources + for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended to resources + for Kustomize apps + type: string + version: + description: Version controls which version of Kustomize + to use for rendering manifests + type: string + type: object + path: + description: Path is a directory path within the Git repository, + and is only valid for applications sourced from Git. + type: string + plugin: + description: Plugin holds config management plugin specific + options + properties: + env: + description: Env is a list of environment variable entries + items: + description: EnvEntry represents an entry in the application's + environment + properties: + name: + description: Name is the name of the variable, usually + expressed in uppercase + type: string + value: + description: Value is the value of the variable + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + description: Array is the value of an array type parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map type parameter. + type: object + name: + description: Name is the name identifying a parameter. + type: string + string: + description: String_ is the value of a string type + parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source within sources + field. This field will not be used if used with a `source` + tag. + type: string + repoURL: + description: RepoURL is the URL to the repository (Git or Helm) + that contains the application manifests + type: string + targetRevision: + description: TargetRevision defines the revision of the source + to sync the application to. In case of Git, this can be commit, + tag, or branch. If omitted, will equal to HEAD. In case of + Helm, this is a semver tag for the Chart's version. + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + description: SyncPolicy controls when and how a sync will be performed + properties: + automated: + description: Automated will keep an application synced to the + target revision + properties: + allowEmpty: + description: 'AllowEmpty allows apps have zero live resources + (default: false)' + type: boolean + prune: + description: 'Prune specifies whether to delete resources + from the cluster that are not found in the sources anymore + as part of automated sync (default: false)' + type: boolean + selfHeal: + description: 'SelfHeal specifes whether to revert resources + back to their desired state upon modification in the cluster + (default: false)' + type: boolean + type: object + managedNamespaceMetadata: + description: ManagedNamespaceMetadata controls metadata in the + given namespace (if CreateNamespace=true) + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + description: Retry controls failed sync retry behavior + properties: + backoff: + description: Backoff controls how to backoff on subsequent + retries of failed syncs + properties: + duration: + description: Duration is the amount to back off. Default + unit is seconds, but could also be a duration (e.g. + "2m", "1h") + type: string + factor: + description: Factor is a factor to multiply the base duration + after each failed retry + format: int64 + type: integer + maxDuration: + description: MaxDuration is the maximum amount of time + allowed for the backoff strategy + type: string + type: object + limit: + description: Limit is the maximum number of attempts for retrying + a failed sync. If set to 0, no retries will be performed. + format: int64 + type: integer + type: object + syncOptions: + description: Options allow you to specify whole app sync-options + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + status: + description: ApplicationStatus contains status information for the application + properties: + conditions: + description: Conditions is a list of currently observed application + conditions + items: + description: ApplicationCondition contains details about an application + condition, which is usally an error or warning + properties: + lastTransitionTime: + description: LastTransitionTime is the time the condition was + last observed + format: date-time + type: string + message: + description: Message contains human-readable message indicating + details about condition + type: string + type: + description: Type is an application condition type + type: string + required: + - message + - type + type: object + type: array + health: + description: Health contains information about the application's current + health status + properties: + message: + description: Message is a human-readable informational message + describing the health status + type: string + status: + description: Status holds the status code of the application or + resource + type: string + type: object + history: + description: History contains information about the application's + sync history + items: + description: RevisionHistory contains history information about + a previous sync + properties: + deployStartedAt: + description: DeployStartedAt holds the time the sync operation + started + format: date-time + type: string + deployedAt: + description: DeployedAt holds the time the sync operation completed + format: date-time + type: string + id: + description: ID is an auto incrementing identifier of the RevisionHistory format: int64 type: integer revision: description: Revision holds the revision the sync was performed against type: string + revisions: + description: Revisions holds the revision of each source in + sources field the sync was performed against + items: + type: string + type: array source: description: Source is a reference to the application source used for the sync operation @@ -1016,149 +1561,422 @@ spec: type: string type: object type: array - passCredentials: - description: PassCredentials pass credentials to all - domains (Helm's --pass-credentials) - type: boolean - releaseName: - description: ReleaseName is the Helm release name to - use. If omitted it will use the application name + passCredentials: + description: PassCredentials pass credentials to all + domains (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release name to + use. If omitted it will use the application name + type: string + skipCrds: + description: SkipCrds skips custom resource definition + installation step (Helm's --skip-crds) + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value files + to use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to be passed + to helm template, typically defined as a block + type: string + version: + description: Version is the Helm version to use for + templating ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific options + properties: + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of additional + annotations to add to rendered manifests + type: object + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional labels + to add to rendered manifests + type: object + forceCommonAnnotations: + description: ForceCommonAnnotations specifies whether + to force applying common annotations to resources + for Kustomize apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether to + force applying common labels to resources for Kustomize + apps + type: boolean + images: + description: Images is a list of Kustomize image override + specifications + items: + description: KustomizeImage represents a Kustomize + image definition in the format [old_image_name=]: + type: string + type: array + namePrefix: + description: NamePrefix is a prefix appended to resources + for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended to resources + for Kustomize apps + type: string + version: + description: Version controls which version of Kustomize + to use for rendering manifests + type: string + type: object + path: + description: Path is a directory path within the Git repository, + and is only valid for applications sourced from Git. + type: string + plugin: + description: Plugin holds config management plugin specific + options + properties: + env: + description: Env is a list of environment variable entries + items: + description: EnvEntry represents an entry in the application's + environment + properties: + name: + description: Name is the name of the variable, + usually expressed in uppercase + type: string + value: + description: Value is the value of the variable + type: string + required: + - name + - value + type: object + type: array + name: type: string - skipCrds: - description: SkipCrds skips custom resource definition - installation step (Helm's --skip-crds) - type: boolean - valueFiles: - description: ValuesFiles is a list of Helm value files - to use when generating a template + parameters: items: - type: string + properties: + array: + description: Array is the value of an array type + parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map type parameter. + type: object + name: + description: Name is the name identifying a parameter. + type: string + string: + description: String_ is the value of a string + type parameter. + type: string + type: object type: array - values: - description: Values specifies Helm values to be passed - to helm template, typically defined as a block - type: string - version: - description: Version is the Helm version to use for - templating ("3") - type: string type: object - kustomize: - description: Kustomize holds kustomize specific options - properties: - commonAnnotations: - additionalProperties: + ref: + description: Ref is reference to another source within sources + field. This field will not be used if used with a `source` + tag. + type: string + repoURL: + description: RepoURL is the URL to the repository (Git or + Helm) that contains the application manifests + type: string + targetRevision: + description: TargetRevision defines the revision of the + source to sync the application to. In case of Git, this + can be commit, tag, or branch. If omitted, will equal + to HEAD. In case of Helm, this is a semver tag for the + Chart's version. + type: string + required: + - repoURL + type: object + sources: + description: Sources is a reference to the application sources + used for the sync operation + items: + description: ApplicationSource contains all required information + about the source of an application + properties: + chart: + description: Chart is a Helm chart name, and must be specified + for applications sourced from a Helm repo. + type: string + directory: + description: Directory holds path/directory specific options + properties: + exclude: + description: Exclude contains a glob pattern to match + paths against that should be explicitly excluded + from being used during manifest generation type: string - description: CommonAnnotations is a list of additional - annotations to add to rendered manifests - type: object - commonLabels: - additionalProperties: + include: + description: Include contains a glob pattern to match + paths against that should be explicitly included + during manifest generation + type: string + jsonnet: + description: Jsonnet holds options specific to Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet External + Variables + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level + Arguments + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan a directory + recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options + properties: + fileParameters: + description: FileParameters are file parameters to + the helm template + items: + description: HelmFileParameter is a file parameter + that's passed to helm template during manifest + generation + properties: + name: + description: Name is the name of the Helm parameter + type: string + path: + description: Path is the path to the file containing + the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents helm + template from failing when valueFiles do not exist + locally by not appending them to helm template --values + type: boolean + parameters: + description: Parameters is a list of Helm parameters + which are passed to the helm template command upon + manifest generation + items: + description: HelmParameter is a parameter that's + passed to helm template during manifest generation + properties: + forceString: + description: ForceString determines whether + to tell Helm to interpret booleans and numbers + as strings + type: boolean + name: + description: Name is the name of the Helm parameter + type: string + value: + description: Value is the value for the Helm + parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials to all + domains (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release name + to use. If omitted it will use the application name + type: string + skipCrds: + description: SkipCrds skips custom resource definition + installation step (Helm's --skip-crds) + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value files + to use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to be passed + to helm template, typically defined as a block + type: string + version: + description: Version is the Helm version to use for + templating ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific options + properties: + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of additional + annotations to add to rendered manifests + type: object + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional + labels to add to rendered manifests + type: object + forceCommonAnnotations: + description: ForceCommonAnnotations specifies whether + to force applying common annotations to resources + for Kustomize apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether to + force applying common labels to resources for Kustomize + apps + type: boolean + images: + description: Images is a list of Kustomize image override + specifications + items: + description: KustomizeImage represents a Kustomize + image definition in the format [old_image_name=]: + type: string + type: array + namePrefix: + description: NamePrefix is a prefix appended to resources + for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended to resources + for Kustomize apps + type: string + version: + description: Version controls which version of Kustomize + to use for rendering manifests type: string - description: CommonLabels is a list of additional labels - to add to rendered manifests - type: object - forceCommonAnnotations: - description: ForceCommonAnnotations specifies whether - to force applying common annotations to resources - for Kustomize apps - type: boolean - forceCommonLabels: - description: ForceCommonLabels specifies whether to - force applying common labels to resources for Kustomize - apps - type: boolean - images: - description: Images is a list of Kustomize image override - specifications - items: - description: KustomizeImage represents a Kustomize - image definition in the format [old_image_name=]: + type: object + path: + description: Path is a directory path within the Git repository, + and is only valid for applications sourced from Git. + type: string + plugin: + description: Plugin holds config management plugin specific + options + properties: + env: + description: Env is a list of environment variable + entries + items: + description: EnvEntry represents an entry in the + application's environment + properties: + name: + description: Name is the name of the variable, + usually expressed in uppercase + type: string + value: + description: Value is the value of the variable + type: string + required: + - name + - value + type: object + type: array + name: type: string - type: array - namePrefix: - description: NamePrefix is a prefix appended to resources - for Kustomize apps - type: string - nameSuffix: - description: NameSuffix is a suffix appended to resources - for Kustomize apps - type: string - version: - description: Version controls which version of Kustomize - to use for rendering manifests - type: string - type: object - path: - description: Path is a directory path within the Git repository, - and is only valid for applications sourced from Git. - type: string - plugin: - description: Plugin holds config management plugin specific - options - properties: - env: - description: Env is a list of environment variable entries - items: - description: EnvEntry represents an entry in the application's - environment - properties: - name: - description: Name is the name of the variable, - usually expressed in uppercase - type: string - value: - description: Value is the value of the variable - type: string - required: - - name - - value - type: object - type: array - name: - type: string - parameters: - items: - properties: - array: - description: Array is the value of an array type - parameter. - items: + parameters: + items: + properties: + array: + description: Array is the value of an array + type parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map type + parameter. + type: object + name: + description: Name is the name identifying a + parameter. type: string - type: array - map: - additionalProperties: + string: + description: String_ is the value of a string + type parameter. type: string - description: Map is the value of a map type parameter. - type: object - name: - description: Name is the name identifying a parameter. - type: string - string: - description: String_ is the value of a string - type parameter. - type: string - type: object - type: array - type: object - repoURL: - description: RepoURL is the URL to the repository (Git or - Helm) that contains the application manifests - type: string - targetRevision: - description: TargetRevision defines the revision of the - source to sync the application to. In case of Git, this - can be commit, tag, or branch. If omitted, will equal - to HEAD. In case of Helm, this is a semver tag for the - Chart's version. - type: string - required: - - repoURL - type: object + type: object + type: array + type: object + ref: + description: Ref is reference to another source within + sources field. This field will not be used if used with + a `source` tag. + type: string + repoURL: + description: RepoURL is the URL to the repository (Git + or Helm) that contains the application manifests + type: string + targetRevision: + description: TargetRevision defines the revision of the + source to sync the application to. In case of Git, this + can be commit, tag, or branch. If omitted, will equal + to HEAD. In case of Helm, this is a semver tag for the + Chart's version. + type: string + required: + - repoURL + type: object + type: array required: - deployedAt - id - - revision type: object type: array observedAt: @@ -1281,6 +2099,14 @@ spec: (Helm) which to sync the application to If omitted, will use the revision specified in app spec. type: string + revisions: + description: Revisions is the list of revision (Git) or + chart version (Helm) which to sync each source in sources + field for the application to If omitted, will use the + revision specified in app spec. + items: + type: string + type: array source: description: Source overrides the source definition set in the application. This is typically set in a Rollback @@ -1539,6 +2365,11 @@ spec: type: object type: array type: object + ref: + description: Ref is reference to another source within + sources field. This field will not be used if used + with a `source` tag. + type: string repoURL: description: RepoURL is the URL to the repository (Git or Helm) that contains the application manifests @@ -1553,6 +2384,291 @@ spec: required: - repoURL type: object + sources: + description: Sources overrides the source definition set + in the application. This is typically set in a Rollback + operation and is nil during a Sync operation + items: + description: ApplicationSource contains all required + information about the source of an application + properties: + chart: + description: Chart is a Helm chart name, and must + be specified for applications sourced from a Helm + repo. + type: string + directory: + description: Directory holds path/directory specific + options + properties: + exclude: + description: Exclude contains a glob pattern + to match paths against that should be explicitly + excluded from being used during manifest generation + type: string + include: + description: Include contains a glob pattern + to match paths against that should be explicitly + included during manifest generation + type: string + jsonnet: + description: Jsonnet holds options specific + to Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet + External Variables + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest + generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level + Arguments + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest + generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan + a directory recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options + properties: + fileParameters: + description: FileParameters are file parameters + to the helm template + items: + description: HelmFileParameter is a file parameter + that's passed to helm template during manifest + generation + properties: + name: + description: Name is the name of the Helm + parameter + type: string + path: + description: Path is the path to the file + containing the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents + helm template from failing when valueFiles + do not exist locally by not appending them + to helm template --values + type: boolean + parameters: + description: Parameters is a list of Helm parameters + which are passed to the helm template command + upon manifest generation + items: + description: HelmParameter is a parameter + that's passed to helm template during manifest + generation + properties: + forceString: + description: ForceString determines whether + to tell Helm to interpret booleans and + numbers as strings + type: boolean + name: + description: Name is the name of the Helm + parameter + type: string + value: + description: Value is the value for the + Helm parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials + to all domains (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release + name to use. If omitted it will use the application + name + type: string + skipCrds: + description: SkipCrds skips custom resource + definition installation step (Helm's --skip-crds) + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value + files to use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to + be passed to helm template, typically defined + as a block + type: string + version: + description: Version is the Helm version to + use for templating ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific + options + properties: + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of + additional annotations to add to rendered + manifests + type: object + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional + labels to add to rendered manifests + type: object + forceCommonAnnotations: + description: ForceCommonAnnotations specifies + whether to force applying common annotations + to resources for Kustomize apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether + to force applying common labels to resources + for Kustomize apps + type: boolean + images: + description: Images is a list of Kustomize image + override specifications + items: + description: KustomizeImage represents a Kustomize + image definition in the format [old_image_name=]: + type: string + type: array + namePrefix: + description: NamePrefix is a prefix appended + to resources for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended + to resources for Kustomize apps + type: string + version: + description: Version controls which version + of Kustomize to use for rendering manifests + type: string + type: object + path: + description: Path is a directory path within the + Git repository, and is only valid for applications + sourced from Git. + type: string + plugin: + description: Plugin holds config management plugin + specific options + properties: + env: + description: Env is a list of environment variable + entries + items: + description: EnvEntry represents an entry + in the application's environment + properties: + name: + description: Name is the name of the variable, + usually expressed in uppercase + type: string + value: + description: Value is the value of the + variable + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + description: Array is the value of an + array type parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map + type parameter. + type: object + name: + description: Name is the name identifying + a parameter. + type: string + string: + description: String_ is the value of a + string type parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source + within sources field. This field will not be used + if used with a `source` tag. + type: string + repoURL: + description: RepoURL is the URL to the repository + (Git or Helm) that contains the application manifests + type: string + targetRevision: + description: TargetRevision defines the revision + of the source to sync the application to. In case + of Git, this can be commit, tag, or branch. If + omitted, will equal to HEAD. In case of Helm, + this is a semver tag for the Chart's version. + type: string + required: + - repoURL + type: object + type: array syncOptions: description: SyncOptions provide per-sync sync-options, e.g. Validate=false @@ -1662,6 +2778,12 @@ spec: description: Revision holds the revision this sync operation was performed to type: string + revisions: + description: Revisions holds the revision this sync operation + was performed for respective indexed source in sources field + items: + type: string + type: array source: description: Source records the application source information of the sync, used for comparing auto-sync @@ -1908,6 +3030,11 @@ spec: type: object type: array type: object + ref: + description: Ref is reference to another source within + sources field. This field will not be used if used with + a `source` tag. + type: string repoURL: description: RepoURL is the URL to the repository (Git or Helm) that contains the application manifests @@ -1922,6 +3049,284 @@ spec: required: - repoURL type: object + sources: + description: Source records the application source information + of the sync, used for comparing auto-sync + items: + description: ApplicationSource contains all required information + about the source of an application + properties: + chart: + description: Chart is a Helm chart name, and must be + specified for applications sourced from a Helm repo. + type: string + directory: + description: Directory holds path/directory specific + options + properties: + exclude: + description: Exclude contains a glob pattern to + match paths against that should be explicitly + excluded from being used during manifest generation + type: string + include: + description: Include contains a glob pattern to + match paths against that should be explicitly + included during manifest generation + type: string + jsonnet: + description: Jsonnet holds options specific to Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet External + Variables + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest + generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level + Arguments + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest + generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan a + directory recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options + properties: + fileParameters: + description: FileParameters are file parameters + to the helm template + items: + description: HelmFileParameter is a file parameter + that's passed to helm template during manifest + generation + properties: + name: + description: Name is the name of the Helm + parameter + type: string + path: + description: Path is the path to the file + containing the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents helm + template from failing when valueFiles do not exist + locally by not appending them to helm template + --values + type: boolean + parameters: + description: Parameters is a list of Helm parameters + which are passed to the helm template command + upon manifest generation + items: + description: HelmParameter is a parameter that's + passed to helm template during manifest generation + properties: + forceString: + description: ForceString determines whether + to tell Helm to interpret booleans and numbers + as strings + type: boolean + name: + description: Name is the name of the Helm + parameter + type: string + value: + description: Value is the value for the Helm + parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials to + all domains (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release name + to use. If omitted it will use the application + name + type: string + skipCrds: + description: SkipCrds skips custom resource definition + installation step (Helm's --skip-crds) + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value + files to use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to be + passed to helm template, typically defined as + a block + type: string + version: + description: Version is the Helm version to use + for templating ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific options + properties: + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of additional + annotations to add to rendered manifests + type: object + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional + labels to add to rendered manifests + type: object + forceCommonAnnotations: + description: ForceCommonAnnotations specifies whether + to force applying common annotations to resources + for Kustomize apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether + to force applying common labels to resources for + Kustomize apps + type: boolean + images: + description: Images is a list of Kustomize image + override specifications + items: + description: KustomizeImage represents a Kustomize + image definition in the format [old_image_name=]: + type: string + type: array + namePrefix: + description: NamePrefix is a prefix appended to + resources for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended to + resources for Kustomize apps + type: string + version: + description: Version controls which version of Kustomize + to use for rendering manifests + type: string + type: object + path: + description: Path is a directory path within the Git + repository, and is only valid for applications sourced + from Git. + type: string + plugin: + description: Plugin holds config management plugin specific + options + properties: + env: + description: Env is a list of environment variable + entries + items: + description: EnvEntry represents an entry in the + application's environment + properties: + name: + description: Name is the name of the variable, + usually expressed in uppercase + type: string + value: + description: Value is the value of the variable + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + description: Array is the value of an array + type parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map type + parameter. + type: object + name: + description: Name is the name identifying + a parameter. + type: string + string: + description: String_ is the value of a string + type parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source within + sources field. This field will not be used if used + with a `source` tag. + type: string + repoURL: + description: RepoURL is the URL to the repository (Git + or Helm) that contains the application manifests + type: string + targetRevision: + description: TargetRevision defines the revision of + the source to sync the application to. In case of + Git, this can be commit, tag, or branch. If omitted, + will equal to HEAD. In case of Helm, this is a semver + tag for the Chart's version. + type: string + required: + - repoURL + type: object + type: array required: - revision type: object @@ -1985,6 +3390,14 @@ spec: sourceType: description: SourceType specifies the type of this application type: string + sourceTypes: + description: SourceTypes specifies the type of the sources included + in the application + items: + description: ApplicationSourceType specifies the type of the application's + source + type: string + type: array summary: description: Summary contains a list of URLs and container images used by this application @@ -2274,6 +3687,11 @@ spec: type: object type: array type: object + ref: + description: Ref is reference to another source within + sources field. This field will not be used if used with + a `source` tag. + type: string repoURL: description: RepoURL is the URL to the repository (Git or Helm) that contains the application manifests @@ -2288,14 +3706,297 @@ spec: required: - repoURL type: object + sources: + description: Sources is a reference to the application's multiple + sources used for comparison + items: + description: ApplicationSource contains all required information + about the source of an application + properties: + chart: + description: Chart is a Helm chart name, and must be + specified for applications sourced from a Helm repo. + type: string + directory: + description: Directory holds path/directory specific + options + properties: + exclude: + description: Exclude contains a glob pattern to + match paths against that should be explicitly + excluded from being used during manifest generation + type: string + include: + description: Include contains a glob pattern to + match paths against that should be explicitly + included during manifest generation + type: string + jsonnet: + description: Jsonnet holds options specific to Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet External + Variables + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest + generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level + Arguments + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest + generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan a + directory recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options + properties: + fileParameters: + description: FileParameters are file parameters + to the helm template + items: + description: HelmFileParameter is a file parameter + that's passed to helm template during manifest + generation + properties: + name: + description: Name is the name of the Helm + parameter + type: string + path: + description: Path is the path to the file + containing the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents helm + template from failing when valueFiles do not exist + locally by not appending them to helm template + --values + type: boolean + parameters: + description: Parameters is a list of Helm parameters + which are passed to the helm template command + upon manifest generation + items: + description: HelmParameter is a parameter that's + passed to helm template during manifest generation + properties: + forceString: + description: ForceString determines whether + to tell Helm to interpret booleans and numbers + as strings + type: boolean + name: + description: Name is the name of the Helm + parameter + type: string + value: + description: Value is the value for the Helm + parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials to + all domains (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release name + to use. If omitted it will use the application + name + type: string + skipCrds: + description: SkipCrds skips custom resource definition + installation step (Helm's --skip-crds) + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value + files to use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to be + passed to helm template, typically defined as + a block + type: string + version: + description: Version is the Helm version to use + for templating ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific options + properties: + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of additional + annotations to add to rendered manifests + type: object + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional + labels to add to rendered manifests + type: object + forceCommonAnnotations: + description: ForceCommonAnnotations specifies whether + to force applying common annotations to resources + for Kustomize apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether + to force applying common labels to resources for + Kustomize apps + type: boolean + images: + description: Images is a list of Kustomize image + override specifications + items: + description: KustomizeImage represents a Kustomize + image definition in the format [old_image_name=]: + type: string + type: array + namePrefix: + description: NamePrefix is a prefix appended to + resources for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended to + resources for Kustomize apps + type: string + version: + description: Version controls which version of Kustomize + to use for rendering manifests + type: string + type: object + path: + description: Path is a directory path within the Git + repository, and is only valid for applications sourced + from Git. + type: string + plugin: + description: Plugin holds config management plugin specific + options + properties: + env: + description: Env is a list of environment variable + entries + items: + description: EnvEntry represents an entry in the + application's environment + properties: + name: + description: Name is the name of the variable, + usually expressed in uppercase + type: string + value: + description: Value is the value of the variable + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + description: Array is the value of an array + type parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map type + parameter. + type: object + name: + description: Name is the name identifying + a parameter. + type: string + string: + description: String_ is the value of a string + type parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source within + sources field. This field will not be used if used + with a `source` tag. + type: string + repoURL: + description: RepoURL is the URL to the repository (Git + or Helm) that contains the application manifests + type: string + targetRevision: + description: TargetRevision defines the revision of + the source to sync the application to. In case of + Git, this can be commit, tag, or branch. If omitted, + will equal to HEAD. In case of Helm, this is a semver + tag for the Chart's version. + type: string + required: + - repoURL + type: object + type: array required: - destination - - source type: object revision: description: Revision contains information about the revision the comparison has been performed to type: string + revisions: + description: Revisions contains information about the revisions + of multiple sources the comparison has been performed to + items: + type: string + type: array status: description: Status is the sync state of the comparison type: string @@ -2601,6 +4302,8 @@ spec: type: object type: array type: object + ref: + type: string repoURL: type: string targetRevision: @@ -2608,6 +4311,165 @@ spec: required: - repoURL type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array syncPolicy: properties: automated: @@ -2654,7 +4516,6 @@ spec: required: - destination - project - - source type: object required: - metadata @@ -2916,6 +4777,8 @@ spec: type: object type: array type: object + ref: + type: string repoURL: type: string targetRevision: @@ -2923,6 +4786,165 @@ spec: required: - repoURL type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array syncPolicy: properties: automated: @@ -2969,7 +4991,6 @@ spec: required: - destination - project - - source type: object required: - metadata @@ -3214,34 +5235,195 @@ spec: - name - value type: object - type: array - name: - type: string - parameters: - items: - properties: - array: - items: + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: type: string - type: array - map: - additionalProperties: + value: type: string - type: object - name: - type: string - string: - type: string - type: object - type: array - type: object - repoURL: - type: string - targetRevision: - type: string - required: - - repoURL - type: object + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array syncPolicy: properties: automated: @@ -3288,7 +5470,6 @@ spec: required: - destination - project - - source type: object required: - metadata @@ -3529,6 +5710,8 @@ spec: type: object type: array type: object + ref: + type: string repoURL: type: string targetRevision: @@ -3536,6 +5719,165 @@ spec: required: - repoURL type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array syncPolicy: properties: automated: @@ -3582,7 +5924,6 @@ spec: required: - destination - project - - source type: object required: - metadata @@ -3852,6 +6193,8 @@ spec: type: object type: array type: object + ref: + type: string repoURL: type: string targetRevision: @@ -3859,6 +6202,165 @@ spec: required: - repoURL type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array syncPolicy: properties: automated: @@ -3905,7 +6407,6 @@ spec: required: - destination - project - - source type: object required: - metadata @@ -4155,25 +6656,186 @@ spec: array: items: type: string - type: array - map: - additionalProperties: + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: type: string - type: object - name: - type: string - string: - type: string - type: object - type: array - type: object - repoURL: - type: string - targetRevision: - type: string - required: - - repoURL - type: object + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array syncPolicy: properties: automated: @@ -4220,7 +6882,6 @@ spec: required: - destination - project - - source type: object required: - metadata @@ -4486,6 +7147,8 @@ spec: type: object type: array type: object + ref: + type: string repoURL: type: string targetRevision: @@ -4493,6 +7156,165 @@ spec: required: - repoURL type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array syncPolicy: properties: automated: @@ -4539,7 +7361,6 @@ spec: required: - destination - project - - source type: object required: - metadata @@ -4780,6 +7601,8 @@ spec: type: object type: array type: object + ref: + type: string repoURL: type: string targetRevision: @@ -4787,6 +7610,165 @@ spec: required: - repoURL type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array syncPolicy: properties: automated: @@ -4833,7 +7815,6 @@ spec: required: - destination - project - - source type: object required: - metadata @@ -5191,6 +8172,8 @@ spec: type: object type: array type: object + ref: + type: string repoURL: type: string targetRevision: @@ -5198,6 +8181,165 @@ spec: required: - repoURL type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array syncPolicy: properties: automated: @@ -5244,7 +8386,6 @@ spec: required: - destination - project - - source type: object required: - metadata @@ -5649,6 +8790,8 @@ spec: type: object type: array type: object + ref: + type: string repoURL: type: string targetRevision: @@ -5656,6 +8799,165 @@ spec: required: - repoURL type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array syncPolicy: properties: automated: @@ -5702,7 +9004,6 @@ spec: required: - destination - project - - source type: object required: - metadata @@ -5946,25 +9247,186 @@ spec: array: items: type: string - type: array - map: - additionalProperties: + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: type: string - type: object - name: - type: string - string: - type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string type: object - type: array - type: object - repoURL: - type: string - targetRevision: - type: string - required: - - repoURL - type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array syncPolicy: properties: automated: @@ -6011,7 +9473,6 @@ spec: required: - destination - project - - source type: object required: - metadata @@ -6281,6 +9742,8 @@ spec: type: object type: array type: object + ref: + type: string repoURL: type: string targetRevision: @@ -6288,6 +9751,165 @@ spec: required: - repoURL type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array syncPolicy: properties: automated: @@ -6334,7 +9956,6 @@ spec: required: - destination - project - - source type: object required: - metadata @@ -6596,6 +10217,8 @@ spec: type: object type: array type: object + ref: + type: string repoURL: type: string targetRevision: @@ -6603,6 +10226,165 @@ spec: required: - repoURL type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array syncPolicy: properties: automated: @@ -6649,7 +10431,6 @@ spec: required: - destination - project - - source type: object required: - metadata @@ -6915,6 +10696,8 @@ spec: type: object type: array type: object + ref: + type: string repoURL: type: string targetRevision: @@ -6922,6 +10705,165 @@ spec: required: - repoURL type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array syncPolicy: properties: automated: @@ -6968,7 +10910,6 @@ spec: required: - destination - project - - source type: object required: - metadata @@ -7209,6 +11150,8 @@ spec: type: object type: array type: object + ref: + type: string repoURL: type: string targetRevision: @@ -7216,6 +11159,165 @@ spec: required: - repoURL type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array syncPolicy: properties: automated: @@ -7262,7 +11364,6 @@ spec: required: - destination - project - - source type: object required: - metadata @@ -7620,6 +11721,8 @@ spec: type: object type: array type: object + ref: + type: string repoURL: type: string targetRevision: @@ -7627,6 +11730,165 @@ spec: required: - repoURL type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array syncPolicy: properties: automated: @@ -7673,7 +11935,6 @@ spec: required: - destination - project - - source type: object required: - metadata @@ -8078,6 +12339,8 @@ spec: type: object type: array type: object + ref: + type: string repoURL: type: string targetRevision: @@ -8085,6 +12348,165 @@ spec: required: - repoURL type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array syncPolicy: properties: automated: @@ -8131,7 +12553,6 @@ spec: required: - destination - project - - source type: object required: - metadata @@ -8391,6 +12812,8 @@ spec: type: object type: array type: object + ref: + type: string repoURL: type: string targetRevision: @@ -8398,6 +12821,165 @@ spec: required: - repoURL type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array syncPolicy: properties: automated: @@ -8444,7 +13026,6 @@ spec: required: - destination - project - - source type: object required: - metadata @@ -8787,25 +13368,186 @@ spec: array: items: type: string - type: array - map: - additionalProperties: + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: type: string - type: object - name: - type: string - string: - type: string - type: object - type: array - type: object - repoURL: - type: string - targetRevision: - type: string - required: - - repoURL - type: object + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array syncPolicy: properties: automated: @@ -8852,7 +13594,6 @@ spec: required: - destination - project - - source type: object required: - metadata @@ -9257,6 +13998,8 @@ spec: type: object type: array type: object + ref: + type: string repoURL: type: string targetRevision: @@ -9264,6 +14007,165 @@ spec: required: - repoURL type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array syncPolicy: properties: automated: @@ -9310,7 +14212,6 @@ spec: required: - destination - project - - source type: object required: - metadata @@ -9573,6 +14474,8 @@ spec: type: object type: array type: object + ref: + type: string repoURL: type: string targetRevision: @@ -9580,6 +14483,165 @@ spec: required: - repoURL type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array syncPolicy: properties: automated: @@ -9626,7 +14688,6 @@ spec: required: - destination - project - - source type: object required: - metadata diff --git a/mkdocs.yml b/mkdocs.yml index 208b28f7724b3..edfa24d231c45 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -135,6 +135,7 @@ nav: - user-guide/tool_detection.md - user-guide/projects.md - user-guide/private-repositories.md + - user-guide/multiple_sources.md - GnuPG verification: user-guide/gpg-verification.md - user-guide/auto_sync.md - user-guide/diffing.md diff --git a/pkg/apis/api-rules/violation_exceptions.list b/pkg/apis/api-rules/violation_exceptions.list index 9cef442f99fa3..0cfc6780de2db 100644 --- a/pkg/apis/api-rules/violation_exceptions.list +++ b/pkg/apis/api-rules/violation_exceptions.list @@ -21,6 +21,7 @@ API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/ap API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,ApplicationSpec,Info API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,ApplicationStatus,Conditions API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,ApplicationStatus,Resources +API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,ApplicationStatus,SourceTypes API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,ApplicationSummary,ExternalURLs API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,ApplicationSummary,Images API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,ApplicationTree,Hosts @@ -65,12 +66,16 @@ API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/ap API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,ResourceNode,Info API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,ResourceNode,ParentRefs API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,ResourceOverride,KnownTypeFields +API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,RevisionHistory,Revisions API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,RevisionMetadata,Tags API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,SCMProviderGenerator,Filters API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,SCMProviderGeneratorFilter,PathsDoNotExist API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,SCMProviderGeneratorFilter,PathsExist API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,SyncOperation,Manifests API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,SyncOperation,Resources +API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,SyncOperation,Revisions +API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,SyncOperationResult,Revisions +API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,SyncStatus,Revisions API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,SyncWindow,Applications API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,SyncWindow,Clusters API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,SyncWindow,Namespaces @@ -88,6 +93,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,KustomizeOptions,BinaryPath API rule violation: names_match,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,KustomizeOptions,BuildOptions API rule violation: names_match,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,PullRequestGenerator,GitLab +API rule violation: names_match,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,RefTarget,Chart +API rule violation: names_match,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,RefTarget,Repo +API rule violation: names_match,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,RefTarget,TargetRevision API rule violation: names_match,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,RepoCreds,GitHubAppEnterpriseBaseURL API rule violation: names_match,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,RepoCreds,GithubAppId API rule violation: names_match,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,RepoCreds,GithubAppInstallationId diff --git a/pkg/apis/application/v1alpha1/generated.pb.go b/pkg/apis/application/v1alpha1/generated.pb.go index 9449f334ab458..e110c371a3235 100644 --- a/pkg/apis/application/v1alpha1/generated.pb.go +++ b/pkg/apis/application/v1alpha1/generated.pb.go @@ -2417,10 +2417,38 @@ func (m *PullRequestGeneratorGithub) XXX_DiscardUnknown() { var xxx_messageInfo_PullRequestGeneratorGithub proto.InternalMessageInfo +func (m *RefTarget) Reset() { *m = RefTarget{} } +func (*RefTarget) ProtoMessage() {} +func (*RefTarget) Descriptor() ([]byte, []int) { + return fileDescriptor_030104ce3b95bcac, []int{85} +} +func (m *RefTarget) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *RefTarget) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *RefTarget) XXX_Merge(src proto.Message) { + xxx_messageInfo_RefTarget.Merge(m, src) +} +func (m *RefTarget) XXX_Size() int { + return m.Size() +} +func (m *RefTarget) XXX_DiscardUnknown() { + xxx_messageInfo_RefTarget.DiscardUnknown(m) +} + +var xxx_messageInfo_RefTarget proto.InternalMessageInfo + func (m *RepoCreds) Reset() { *m = RepoCreds{} } func (*RepoCreds) ProtoMessage() {} func (*RepoCreds) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{85} + return fileDescriptor_030104ce3b95bcac, []int{86} } func (m *RepoCreds) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2448,7 +2476,7 @@ var xxx_messageInfo_RepoCreds proto.InternalMessageInfo func (m *RepoCredsList) Reset() { *m = RepoCredsList{} } func (*RepoCredsList) ProtoMessage() {} func (*RepoCredsList) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{86} + return fileDescriptor_030104ce3b95bcac, []int{87} } func (m *RepoCredsList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2476,7 +2504,7 @@ var xxx_messageInfo_RepoCredsList proto.InternalMessageInfo func (m *Repository) Reset() { *m = Repository{} } func (*Repository) ProtoMessage() {} func (*Repository) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{87} + return fileDescriptor_030104ce3b95bcac, []int{88} } func (m *Repository) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2504,7 +2532,7 @@ var xxx_messageInfo_Repository proto.InternalMessageInfo func (m *RepositoryCertificate) Reset() { *m = RepositoryCertificate{} } func (*RepositoryCertificate) ProtoMessage() {} func (*RepositoryCertificate) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{88} + return fileDescriptor_030104ce3b95bcac, []int{89} } func (m *RepositoryCertificate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2532,7 +2560,7 @@ var xxx_messageInfo_RepositoryCertificate proto.InternalMessageInfo func (m *RepositoryCertificateList) Reset() { *m = RepositoryCertificateList{} } func (*RepositoryCertificateList) ProtoMessage() {} func (*RepositoryCertificateList) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{89} + return fileDescriptor_030104ce3b95bcac, []int{90} } func (m *RepositoryCertificateList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2560,7 +2588,7 @@ var xxx_messageInfo_RepositoryCertificateList proto.InternalMessageInfo func (m *RepositoryList) Reset() { *m = RepositoryList{} } func (*RepositoryList) ProtoMessage() {} func (*RepositoryList) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{90} + return fileDescriptor_030104ce3b95bcac, []int{91} } func (m *RepositoryList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2588,7 +2616,7 @@ var xxx_messageInfo_RepositoryList proto.InternalMessageInfo func (m *ResourceAction) Reset() { *m = ResourceAction{} } func (*ResourceAction) ProtoMessage() {} func (*ResourceAction) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{91} + return fileDescriptor_030104ce3b95bcac, []int{92} } func (m *ResourceAction) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2616,7 +2644,7 @@ var xxx_messageInfo_ResourceAction proto.InternalMessageInfo func (m *ResourceActionDefinition) Reset() { *m = ResourceActionDefinition{} } func (*ResourceActionDefinition) ProtoMessage() {} func (*ResourceActionDefinition) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{92} + return fileDescriptor_030104ce3b95bcac, []int{93} } func (m *ResourceActionDefinition) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2644,7 +2672,7 @@ var xxx_messageInfo_ResourceActionDefinition proto.InternalMessageInfo func (m *ResourceActionParam) Reset() { *m = ResourceActionParam{} } func (*ResourceActionParam) ProtoMessage() {} func (*ResourceActionParam) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{93} + return fileDescriptor_030104ce3b95bcac, []int{94} } func (m *ResourceActionParam) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2672,7 +2700,7 @@ var xxx_messageInfo_ResourceActionParam proto.InternalMessageInfo func (m *ResourceActions) Reset() { *m = ResourceActions{} } func (*ResourceActions) ProtoMessage() {} func (*ResourceActions) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{94} + return fileDescriptor_030104ce3b95bcac, []int{95} } func (m *ResourceActions) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2700,7 +2728,7 @@ var xxx_messageInfo_ResourceActions proto.InternalMessageInfo func (m *ResourceDiff) Reset() { *m = ResourceDiff{} } func (*ResourceDiff) ProtoMessage() {} func (*ResourceDiff) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{95} + return fileDescriptor_030104ce3b95bcac, []int{96} } func (m *ResourceDiff) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2728,7 +2756,7 @@ var xxx_messageInfo_ResourceDiff proto.InternalMessageInfo func (m *ResourceIgnoreDifferences) Reset() { *m = ResourceIgnoreDifferences{} } func (*ResourceIgnoreDifferences) ProtoMessage() {} func (*ResourceIgnoreDifferences) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{96} + return fileDescriptor_030104ce3b95bcac, []int{97} } func (m *ResourceIgnoreDifferences) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2756,7 +2784,7 @@ var xxx_messageInfo_ResourceIgnoreDifferences proto.InternalMessageInfo func (m *ResourceNetworkingInfo) Reset() { *m = ResourceNetworkingInfo{} } func (*ResourceNetworkingInfo) ProtoMessage() {} func (*ResourceNetworkingInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{97} + return fileDescriptor_030104ce3b95bcac, []int{98} } func (m *ResourceNetworkingInfo) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2784,7 +2812,7 @@ var xxx_messageInfo_ResourceNetworkingInfo proto.InternalMessageInfo func (m *ResourceNode) Reset() { *m = ResourceNode{} } func (*ResourceNode) ProtoMessage() {} func (*ResourceNode) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{98} + return fileDescriptor_030104ce3b95bcac, []int{99} } func (m *ResourceNode) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2812,7 +2840,7 @@ var xxx_messageInfo_ResourceNode proto.InternalMessageInfo func (m *ResourceOverride) Reset() { *m = ResourceOverride{} } func (*ResourceOverride) ProtoMessage() {} func (*ResourceOverride) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{99} + return fileDescriptor_030104ce3b95bcac, []int{100} } func (m *ResourceOverride) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2840,7 +2868,7 @@ var xxx_messageInfo_ResourceOverride proto.InternalMessageInfo func (m *ResourceRef) Reset() { *m = ResourceRef{} } func (*ResourceRef) ProtoMessage() {} func (*ResourceRef) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{100} + return fileDescriptor_030104ce3b95bcac, []int{101} } func (m *ResourceRef) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2868,7 +2896,7 @@ var xxx_messageInfo_ResourceRef proto.InternalMessageInfo func (m *ResourceResult) Reset() { *m = ResourceResult{} } func (*ResourceResult) ProtoMessage() {} func (*ResourceResult) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{101} + return fileDescriptor_030104ce3b95bcac, []int{102} } func (m *ResourceResult) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2896,7 +2924,7 @@ var xxx_messageInfo_ResourceResult proto.InternalMessageInfo func (m *ResourceStatus) Reset() { *m = ResourceStatus{} } func (*ResourceStatus) ProtoMessage() {} func (*ResourceStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{102} + return fileDescriptor_030104ce3b95bcac, []int{103} } func (m *ResourceStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2924,7 +2952,7 @@ var xxx_messageInfo_ResourceStatus proto.InternalMessageInfo func (m *RetryStrategy) Reset() { *m = RetryStrategy{} } func (*RetryStrategy) ProtoMessage() {} func (*RetryStrategy) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{103} + return fileDescriptor_030104ce3b95bcac, []int{104} } func (m *RetryStrategy) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2952,7 +2980,7 @@ var xxx_messageInfo_RetryStrategy proto.InternalMessageInfo func (m *RevisionHistory) Reset() { *m = RevisionHistory{} } func (*RevisionHistory) ProtoMessage() {} func (*RevisionHistory) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{104} + return fileDescriptor_030104ce3b95bcac, []int{105} } func (m *RevisionHistory) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2980,7 +3008,7 @@ var xxx_messageInfo_RevisionHistory proto.InternalMessageInfo func (m *RevisionMetadata) Reset() { *m = RevisionMetadata{} } func (*RevisionMetadata) ProtoMessage() {} func (*RevisionMetadata) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{105} + return fileDescriptor_030104ce3b95bcac, []int{106} } func (m *RevisionMetadata) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3008,7 +3036,7 @@ var xxx_messageInfo_RevisionMetadata proto.InternalMessageInfo func (m *SCMProviderGenerator) Reset() { *m = SCMProviderGenerator{} } func (*SCMProviderGenerator) ProtoMessage() {} func (*SCMProviderGenerator) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{106} + return fileDescriptor_030104ce3b95bcac, []int{107} } func (m *SCMProviderGenerator) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3036,7 +3064,7 @@ var xxx_messageInfo_SCMProviderGenerator proto.InternalMessageInfo func (m *SCMProviderGeneratorAzureDevOps) Reset() { *m = SCMProviderGeneratorAzureDevOps{} } func (*SCMProviderGeneratorAzureDevOps) ProtoMessage() {} func (*SCMProviderGeneratorAzureDevOps) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{107} + return fileDescriptor_030104ce3b95bcac, []int{108} } func (m *SCMProviderGeneratorAzureDevOps) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3064,7 +3092,7 @@ var xxx_messageInfo_SCMProviderGeneratorAzureDevOps proto.InternalMessageInfo func (m *SCMProviderGeneratorBitbucket) Reset() { *m = SCMProviderGeneratorBitbucket{} } func (*SCMProviderGeneratorBitbucket) ProtoMessage() {} func (*SCMProviderGeneratorBitbucket) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{108} + return fileDescriptor_030104ce3b95bcac, []int{109} } func (m *SCMProviderGeneratorBitbucket) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3092,7 +3120,7 @@ var xxx_messageInfo_SCMProviderGeneratorBitbucket proto.InternalMessageInfo func (m *SCMProviderGeneratorBitbucketServer) Reset() { *m = SCMProviderGeneratorBitbucketServer{} } func (*SCMProviderGeneratorBitbucketServer) ProtoMessage() {} func (*SCMProviderGeneratorBitbucketServer) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{109} + return fileDescriptor_030104ce3b95bcac, []int{110} } func (m *SCMProviderGeneratorBitbucketServer) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3120,7 +3148,7 @@ var xxx_messageInfo_SCMProviderGeneratorBitbucketServer proto.InternalMessageInf func (m *SCMProviderGeneratorFilter) Reset() { *m = SCMProviderGeneratorFilter{} } func (*SCMProviderGeneratorFilter) ProtoMessage() {} func (*SCMProviderGeneratorFilter) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{110} + return fileDescriptor_030104ce3b95bcac, []int{111} } func (m *SCMProviderGeneratorFilter) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3148,7 +3176,7 @@ var xxx_messageInfo_SCMProviderGeneratorFilter proto.InternalMessageInfo func (m *SCMProviderGeneratorGitea) Reset() { *m = SCMProviderGeneratorGitea{} } func (*SCMProviderGeneratorGitea) ProtoMessage() {} func (*SCMProviderGeneratorGitea) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{111} + return fileDescriptor_030104ce3b95bcac, []int{112} } func (m *SCMProviderGeneratorGitea) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3176,7 +3204,7 @@ var xxx_messageInfo_SCMProviderGeneratorGitea proto.InternalMessageInfo func (m *SCMProviderGeneratorGithub) Reset() { *m = SCMProviderGeneratorGithub{} } func (*SCMProviderGeneratorGithub) ProtoMessage() {} func (*SCMProviderGeneratorGithub) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{112} + return fileDescriptor_030104ce3b95bcac, []int{113} } func (m *SCMProviderGeneratorGithub) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3204,7 +3232,7 @@ var xxx_messageInfo_SCMProviderGeneratorGithub proto.InternalMessageInfo func (m *SCMProviderGeneratorGitlab) Reset() { *m = SCMProviderGeneratorGitlab{} } func (*SCMProviderGeneratorGitlab) ProtoMessage() {} func (*SCMProviderGeneratorGitlab) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{113} + return fileDescriptor_030104ce3b95bcac, []int{114} } func (m *SCMProviderGeneratorGitlab) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3232,7 +3260,7 @@ var xxx_messageInfo_SCMProviderGeneratorGitlab proto.InternalMessageInfo func (m *SecretRef) Reset() { *m = SecretRef{} } func (*SecretRef) ProtoMessage() {} func (*SecretRef) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{114} + return fileDescriptor_030104ce3b95bcac, []int{115} } func (m *SecretRef) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3260,7 +3288,7 @@ var xxx_messageInfo_SecretRef proto.InternalMessageInfo func (m *SignatureKey) Reset() { *m = SignatureKey{} } func (*SignatureKey) ProtoMessage() {} func (*SignatureKey) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{115} + return fileDescriptor_030104ce3b95bcac, []int{116} } func (m *SignatureKey) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3288,7 +3316,7 @@ var xxx_messageInfo_SignatureKey proto.InternalMessageInfo func (m *SyncOperation) Reset() { *m = SyncOperation{} } func (*SyncOperation) ProtoMessage() {} func (*SyncOperation) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{116} + return fileDescriptor_030104ce3b95bcac, []int{117} } func (m *SyncOperation) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3316,7 +3344,7 @@ var xxx_messageInfo_SyncOperation proto.InternalMessageInfo func (m *SyncOperationResource) Reset() { *m = SyncOperationResource{} } func (*SyncOperationResource) ProtoMessage() {} func (*SyncOperationResource) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{117} + return fileDescriptor_030104ce3b95bcac, []int{118} } func (m *SyncOperationResource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3344,7 +3372,7 @@ var xxx_messageInfo_SyncOperationResource proto.InternalMessageInfo func (m *SyncOperationResult) Reset() { *m = SyncOperationResult{} } func (*SyncOperationResult) ProtoMessage() {} func (*SyncOperationResult) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{118} + return fileDescriptor_030104ce3b95bcac, []int{119} } func (m *SyncOperationResult) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3372,7 +3400,7 @@ var xxx_messageInfo_SyncOperationResult proto.InternalMessageInfo func (m *SyncPolicy) Reset() { *m = SyncPolicy{} } func (*SyncPolicy) ProtoMessage() {} func (*SyncPolicy) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{119} + return fileDescriptor_030104ce3b95bcac, []int{120} } func (m *SyncPolicy) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3400,7 +3428,7 @@ var xxx_messageInfo_SyncPolicy proto.InternalMessageInfo func (m *SyncPolicyAutomated) Reset() { *m = SyncPolicyAutomated{} } func (*SyncPolicyAutomated) ProtoMessage() {} func (*SyncPolicyAutomated) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{120} + return fileDescriptor_030104ce3b95bcac, []int{121} } func (m *SyncPolicyAutomated) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3428,7 +3456,7 @@ var xxx_messageInfo_SyncPolicyAutomated proto.InternalMessageInfo func (m *SyncStatus) Reset() { *m = SyncStatus{} } func (*SyncStatus) ProtoMessage() {} func (*SyncStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{121} + return fileDescriptor_030104ce3b95bcac, []int{122} } func (m *SyncStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3456,7 +3484,7 @@ var xxx_messageInfo_SyncStatus proto.InternalMessageInfo func (m *SyncStrategy) Reset() { *m = SyncStrategy{} } func (*SyncStrategy) ProtoMessage() {} func (*SyncStrategy) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{122} + return fileDescriptor_030104ce3b95bcac, []int{123} } func (m *SyncStrategy) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3484,7 +3512,7 @@ var xxx_messageInfo_SyncStrategy proto.InternalMessageInfo func (m *SyncStrategyApply) Reset() { *m = SyncStrategyApply{} } func (*SyncStrategyApply) ProtoMessage() {} func (*SyncStrategyApply) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{123} + return fileDescriptor_030104ce3b95bcac, []int{124} } func (m *SyncStrategyApply) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3512,7 +3540,7 @@ var xxx_messageInfo_SyncStrategyApply proto.InternalMessageInfo func (m *SyncStrategyHook) Reset() { *m = SyncStrategyHook{} } func (*SyncStrategyHook) ProtoMessage() {} func (*SyncStrategyHook) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{124} + return fileDescriptor_030104ce3b95bcac, []int{125} } func (m *SyncStrategyHook) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3540,7 +3568,7 @@ var xxx_messageInfo_SyncStrategyHook proto.InternalMessageInfo func (m *SyncWindow) Reset() { *m = SyncWindow{} } func (*SyncWindow) ProtoMessage() {} func (*SyncWindow) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{125} + return fileDescriptor_030104ce3b95bcac, []int{126} } func (m *SyncWindow) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3568,7 +3596,7 @@ var xxx_messageInfo_SyncWindow proto.InternalMessageInfo func (m *TLSClientConfig) Reset() { *m = TLSClientConfig{} } func (*TLSClientConfig) ProtoMessage() {} func (*TLSClientConfig) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{126} + return fileDescriptor_030104ce3b95bcac, []int{127} } func (m *TLSClientConfig) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3692,6 +3720,7 @@ func init() { proto.RegisterType((*PullRequestGeneratorGitLab)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.PullRequestGeneratorGitLab") proto.RegisterType((*PullRequestGeneratorGitea)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.PullRequestGeneratorGitea") proto.RegisterType((*PullRequestGeneratorGithub)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.PullRequestGeneratorGithub") + proto.RegisterType((*RefTarget)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.RefTarget") proto.RegisterType((*RepoCreds)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.RepoCreds") proto.RegisterType((*RepoCredsList)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.RepoCredsList") proto.RegisterType((*Repository)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.Repository") @@ -3743,581 +3772,591 @@ func init() { } var fileDescriptor_030104ce3b95bcac = []byte{ - // 9183 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x7d, 0x6d, 0x6c, 0x24, 0xc9, - 0x75, 0xd8, 0xf5, 0x0c, 0x67, 0x38, 0xf3, 0xf8, 0xb1, 0xcb, 0xda, 0xdd, 0x3b, 0xde, 0xde, 0xdd, - 0x72, 0xd1, 0x07, 0x4b, 0xe7, 0xe8, 0x8e, 0xcc, 0xad, 0x4f, 0xca, 0xc5, 0x67, 0x9f, 0xcc, 0x21, - 0x77, 0xb9, 0xdc, 0xe5, 0xd7, 0x15, 0xb9, 0xbb, 0xd6, 0xc9, 0xfa, 0x68, 0xf6, 0xd4, 0x0c, 0x7b, - 0x39, 0xd3, 0x3d, 0xdb, 0xdd, 0xc3, 0xe5, 0x9c, 0xbf, 0x24, 0x59, 0xb6, 0x95, 0xe8, 0x33, 0x52, - 0x80, 0xc8, 0x40, 0x90, 0x28, 0xb2, 0x61, 0xc4, 0x48, 0x84, 0x38, 0xc8, 0x8f, 0xc4, 0x09, 0xf2, - 0x23, 0x56, 0x7e, 0x28, 0x70, 0x80, 0x08, 0x88, 0x61, 0x39, 0x71, 0x42, 0x9f, 0x18, 0x04, 0xf9, - 0x00, 0xe2, 0x20, 0x8e, 0xfe, 0x64, 0x91, 0x1f, 0x46, 0x7d, 0x57, 0xf7, 0xcc, 0x2c, 0x67, 0xc8, - 0xe6, 0xee, 0x4a, 0xb8, 0x7f, 0x33, 0xf5, 0x5e, 0xbd, 0xf7, 0xaa, 0xba, 0xea, 0xd5, 0xab, 0xaa, - 0xf7, 0x5e, 0xc1, 0x4a, 0xdd, 0x8b, 0x77, 0xda, 0xdb, 0xb3, 0x6e, 0xd0, 0x9c, 0x73, 0xc2, 0x7a, - 0xd0, 0x0a, 0x83, 0xbb, 0xec, 0xc7, 0x2b, 0x6e, 0x75, 0x6e, 0xef, 0xca, 0x5c, 0x6b, 0xb7, 0x3e, - 0xe7, 0xb4, 0xbc, 0x68, 0xce, 0x69, 0xb5, 0x1a, 0x9e, 0xeb, 0xc4, 0x5e, 0xe0, 0xcf, 0xed, 0xbd, - 0xea, 0x34, 0x5a, 0x3b, 0xce, 0xab, 0x73, 0x75, 0xe2, 0x93, 0xd0, 0x89, 0x49, 0x75, 0xb6, 0x15, - 0x06, 0x71, 0x80, 0x7e, 0x4a, 0x53, 0x9b, 0x95, 0xd4, 0xd8, 0x8f, 0x4f, 0xb8, 0xd5, 0xd9, 0xbd, - 0x2b, 0xb3, 0xad, 0xdd, 0xfa, 0x2c, 0xa5, 0x36, 0x6b, 0x50, 0x9b, 0x95, 0xd4, 0x2e, 0xbe, 0x62, - 0xc8, 0x52, 0x0f, 0xea, 0xc1, 0x1c, 0x23, 0xba, 0xdd, 0xae, 0xb1, 0x7f, 0xec, 0x0f, 0xfb, 0xc5, - 0x99, 0x5d, 0xb4, 0x77, 0x5f, 0x8f, 0x66, 0xbd, 0x80, 0x8a, 0x37, 0xe7, 0x06, 0x21, 0x99, 0xdb, - 0xeb, 0x12, 0xe8, 0xe2, 0x75, 0x8d, 0x43, 0xf6, 0x63, 0xe2, 0x47, 0x5e, 0xe0, 0x47, 0xaf, 0x50, - 0x11, 0x48, 0xb8, 0x47, 0x42, 0xb3, 0x79, 0x06, 0x42, 0x2f, 0x4a, 0xaf, 0x69, 0x4a, 0x4d, 0xc7, - 0xdd, 0xf1, 0x7c, 0x12, 0x76, 0x74, 0xf5, 0x26, 0x89, 0x9d, 0x5e, 0xb5, 0xe6, 0xfa, 0xd5, 0x0a, - 0xdb, 0x7e, 0xec, 0x35, 0x49, 0x57, 0x85, 0x0f, 0x1d, 0x55, 0x21, 0x72, 0x77, 0x48, 0xd3, 0x49, - 0xd7, 0xb3, 0xef, 0xc1, 0xc4, 0xfc, 0x9d, 0xcd, 0xf9, 0x76, 0xbc, 0xb3, 0x10, 0xf8, 0x35, 0xaf, - 0x8e, 0x3e, 0x08, 0x63, 0x6e, 0xa3, 0x1d, 0xc5, 0x24, 0x5c, 0x73, 0x9a, 0x64, 0xda, 0xba, 0x6c, - 0xbd, 0x54, 0xae, 0x9c, 0xfb, 0xce, 0xc1, 0xcc, 0x53, 0x87, 0x07, 0x33, 0x63, 0x0b, 0x1a, 0x84, - 0x4d, 0x3c, 0xf4, 0xe3, 0x30, 0x1a, 0x06, 0x0d, 0x32, 0x8f, 0xd7, 0xa6, 0x73, 0xac, 0xca, 0x19, - 0x51, 0x65, 0x14, 0xf3, 0x62, 0x2c, 0xe1, 0xf6, 0x1f, 0xe5, 0x00, 0xe6, 0x5b, 0xad, 0x8d, 0x30, - 0xb8, 0x4b, 0xdc, 0x18, 0x7d, 0x12, 0x4a, 0xb4, 0x17, 0xaa, 0x4e, 0xec, 0x30, 0x6e, 0x63, 0x57, - 0xfe, 0xf2, 0x2c, 0x6f, 0xcc, 0xac, 0xd9, 0x18, 0x3d, 0x06, 0x28, 0xf6, 0xec, 0xde, 0xab, 0xb3, - 0xeb, 0xdb, 0xb4, 0xfe, 0x2a, 0x89, 0x9d, 0x0a, 0x12, 0xcc, 0x40, 0x97, 0x61, 0x45, 0x15, 0xf9, - 0x30, 0x12, 0xb5, 0x88, 0xcb, 0x04, 0x1b, 0xbb, 0xb2, 0x32, 0x7b, 0x92, 0xc1, 0x36, 0xab, 0x25, - 0xdf, 0x6c, 0x11, 0xb7, 0x32, 0x2e, 0x38, 0x8f, 0xd0, 0x7f, 0x98, 0xf1, 0x41, 0x7b, 0x50, 0x8c, - 0x62, 0x27, 0x6e, 0x47, 0xd3, 0x79, 0xc6, 0x71, 0x2d, 0x33, 0x8e, 0x8c, 0x6a, 0x65, 0x52, 0xf0, - 0x2c, 0xf2, 0xff, 0x58, 0x70, 0xb3, 0xff, 0xb3, 0x05, 0x93, 0x1a, 0x79, 0xc5, 0x8b, 0x62, 0xf4, - 0x73, 0x5d, 0x9d, 0x3b, 0x3b, 0x58, 0xe7, 0xd2, 0xda, 0xac, 0x6b, 0xcf, 0x0a, 0x66, 0x25, 0x59, - 0x62, 0x74, 0x6c, 0x13, 0x0a, 0x5e, 0x4c, 0x9a, 0xd1, 0x74, 0xee, 0x72, 0xfe, 0xa5, 0xb1, 0x2b, - 0xd7, 0xb3, 0x6a, 0x67, 0x65, 0x42, 0x30, 0x2d, 0x2c, 0x53, 0xf2, 0x98, 0x73, 0xb1, 0x7f, 0x67, - 0xdc, 0x6c, 0x1f, 0xed, 0x70, 0xf4, 0x2a, 0x8c, 0x45, 0x41, 0x3b, 0x74, 0x09, 0x26, 0xad, 0x20, - 0x9a, 0xb6, 0x2e, 0xe7, 0xe9, 0xd0, 0xa3, 0x23, 0x75, 0x53, 0x17, 0x63, 0x13, 0x07, 0x7d, 0xc9, - 0x82, 0xf1, 0x2a, 0x89, 0x62, 0xcf, 0x67, 0xfc, 0xa5, 0xf0, 0x5b, 0x27, 0x16, 0x5e, 0x16, 0x2e, - 0x6a, 0xe2, 0x95, 0xf3, 0xa2, 0x21, 0xe3, 0x46, 0x61, 0x84, 0x13, 0xfc, 0xe9, 0x8c, 0xab, 0x92, - 0xc8, 0x0d, 0xbd, 0x16, 0xfd, 0xcf, 0xc6, 0x8c, 0x31, 0xe3, 0x16, 0x35, 0x08, 0x9b, 0x78, 0xc8, - 0x87, 0x02, 0x9d, 0x51, 0xd1, 0xf4, 0x08, 0x93, 0x7f, 0xf9, 0x64, 0xf2, 0x8b, 0x4e, 0xa5, 0x93, - 0x55, 0xf7, 0x3e, 0xfd, 0x17, 0x61, 0xce, 0x06, 0x7d, 0xd1, 0x82, 0x69, 0x31, 0xe3, 0x31, 0xe1, - 0x1d, 0x7a, 0x67, 0xc7, 0x8b, 0x49, 0xc3, 0x8b, 0xe2, 0xe9, 0x02, 0x93, 0x61, 0x6e, 0xb0, 0xb1, - 0xb5, 0x14, 0x06, 0xed, 0xd6, 0x4d, 0xcf, 0xaf, 0x56, 0x2e, 0x0b, 0x4e, 0xd3, 0x0b, 0x7d, 0x08, - 0xe3, 0xbe, 0x2c, 0xd1, 0xd7, 0x2c, 0xb8, 0xe8, 0x3b, 0x4d, 0x12, 0xb5, 0x1c, 0xfa, 0x69, 0x39, - 0xb8, 0xd2, 0x70, 0xdc, 0x5d, 0x26, 0x51, 0xf1, 0x78, 0x12, 0xd9, 0x42, 0xa2, 0x8b, 0x6b, 0x7d, - 0x49, 0xe3, 0x87, 0xb0, 0x45, 0xbf, 0x69, 0xc1, 0x54, 0x10, 0xb6, 0x76, 0x1c, 0x9f, 0x54, 0x25, - 0x34, 0x9a, 0x1e, 0x65, 0x53, 0xef, 0xe3, 0x27, 0xfb, 0x44, 0xeb, 0x69, 0xb2, 0xab, 0x81, 0xef, - 0xc5, 0x41, 0xb8, 0x49, 0xe2, 0xd8, 0xf3, 0xeb, 0x51, 0xe5, 0xc2, 0xe1, 0xc1, 0xcc, 0x54, 0x17, - 0x16, 0xee, 0x96, 0x07, 0xfd, 0x3c, 0x8c, 0x45, 0x1d, 0xdf, 0xbd, 0xe3, 0xf9, 0xd5, 0xe0, 0x7e, - 0x34, 0x5d, 0xca, 0x62, 0xfa, 0x6e, 0x2a, 0x82, 0x62, 0x02, 0x6a, 0x06, 0xd8, 0xe4, 0xd6, 0xfb, - 0xc3, 0xe9, 0xa1, 0x54, 0xce, 0xfa, 0xc3, 0xe9, 0xc1, 0xf4, 0x10, 0xb6, 0xe8, 0xd7, 0x2d, 0x98, - 0x88, 0xbc, 0xba, 0xef, 0xc4, 0xed, 0x90, 0xdc, 0x24, 0x9d, 0x68, 0x1a, 0x98, 0x20, 0x37, 0x4e, - 0xd8, 0x2b, 0x06, 0xc9, 0xca, 0x05, 0x21, 0xe3, 0x84, 0x59, 0x1a, 0xe1, 0x24, 0xdf, 0x5e, 0x13, - 0x4d, 0x0f, 0xeb, 0xb1, 0x6c, 0x27, 0x9a, 0x1e, 0xd4, 0x7d, 0x59, 0xa2, 0x9f, 0x81, 0xb3, 0xbc, - 0x48, 0xf5, 0x6c, 0x34, 0x3d, 0xce, 0x14, 0xed, 0xf9, 0xc3, 0x83, 0x99, 0xb3, 0x9b, 0x29, 0x18, - 0xee, 0xc2, 0x46, 0xf7, 0x60, 0xa6, 0x45, 0xc2, 0xa6, 0x17, 0xaf, 0xfb, 0x8d, 0x8e, 0x54, 0xdf, - 0x6e, 0xd0, 0x22, 0x55, 0x21, 0x4e, 0x34, 0x3d, 0x71, 0xd9, 0x7a, 0xa9, 0x54, 0x79, 0xbf, 0x10, - 0x73, 0x66, 0xe3, 0xe1, 0xe8, 0xf8, 0x28, 0x7a, 0xf6, 0xbf, 0xc9, 0xc1, 0xd9, 0xf4, 0xc2, 0x89, - 0x7e, 0xdb, 0x82, 0x33, 0x77, 0xef, 0xc7, 0x5b, 0xc1, 0x2e, 0xf1, 0xa3, 0x4a, 0x87, 0xaa, 0x37, - 0xb6, 0x64, 0x8c, 0x5d, 0x71, 0xb3, 0x5d, 0xa2, 0x67, 0x6f, 0x24, 0xb9, 0x5c, 0xf5, 0xe3, 0xb0, - 0x53, 0x79, 0x46, 0xb4, 0xee, 0xcc, 0x8d, 0x3b, 0x5b, 0x26, 0x14, 0xa7, 0x85, 0xba, 0xf8, 0x79, - 0x0b, 0xce, 0xf7, 0x22, 0x81, 0xce, 0x42, 0x7e, 0x97, 0x74, 0xb8, 0x55, 0x86, 0xe9, 0x4f, 0xf4, - 0x31, 0x28, 0xec, 0x39, 0x8d, 0x36, 0x11, 0xd6, 0xcd, 0xd2, 0xc9, 0x1a, 0xa2, 0x24, 0xc3, 0x9c, - 0xea, 0x4f, 0xe6, 0x5e, 0xb7, 0xec, 0x7f, 0x97, 0x87, 0x31, 0x63, 0x7d, 0x7b, 0x04, 0x16, 0x5b, - 0x90, 0xb0, 0xd8, 0x56, 0x33, 0x5b, 0x9a, 0xfb, 0x9a, 0x6c, 0xf7, 0x53, 0x26, 0xdb, 0x7a, 0x76, - 0x2c, 0x1f, 0x6a, 0xb3, 0xa1, 0x18, 0xca, 0x41, 0x8b, 0x5a, 0xe4, 0x74, 0xe9, 0x1f, 0xc9, 0xe2, - 0x13, 0xae, 0x4b, 0x72, 0x95, 0x89, 0xc3, 0x83, 0x99, 0xb2, 0xfa, 0x8b, 0x35, 0x23, 0xfb, 0x7b, - 0x16, 0x9c, 0x37, 0x64, 0x5c, 0x08, 0xfc, 0xaa, 0xc7, 0x3e, 0xed, 0x65, 0x18, 0x89, 0x3b, 0x2d, - 0x69, 0xf6, 0xab, 0x9e, 0xda, 0xea, 0xb4, 0x08, 0x66, 0x10, 0x6a, 0xe8, 0x37, 0x49, 0x14, 0x39, - 0x75, 0x92, 0x36, 0xf4, 0x57, 0x79, 0x31, 0x96, 0x70, 0x14, 0x02, 0x6a, 0x38, 0x51, 0xbc, 0x15, - 0x3a, 0x7e, 0xc4, 0xc8, 0x6f, 0x79, 0x4d, 0x22, 0x3a, 0xf8, 0x2f, 0x0d, 0x36, 0x62, 0x68, 0x8d, - 0xca, 0xd3, 0x87, 0x07, 0x33, 0x68, 0xa5, 0x8b, 0x12, 0xee, 0x41, 0xdd, 0xfe, 0x9a, 0x05, 0x4f, - 0xf7, 0xb6, 0xc5, 0xd0, 0xfb, 0xa0, 0xc8, 0x77, 0x6f, 0xa2, 0x75, 0xfa, 0x93, 0xb0, 0x52, 0x2c, - 0xa0, 0x68, 0x0e, 0xca, 0x6a, 0x9d, 0x10, 0x6d, 0x9c, 0x12, 0xa8, 0x65, 0xbd, 0xb8, 0x68, 0x1c, - 0xda, 0x69, 0xf4, 0x8f, 0xb0, 0xdc, 0x54, 0xa7, 0xb1, 0x4d, 0x12, 0x83, 0xd8, 0x7f, 0x6a, 0xc1, - 0x19, 0x43, 0xaa, 0x47, 0x60, 0x9a, 0xfb, 0x49, 0xd3, 0x7c, 0x39, 0xb3, 0xf1, 0xdc, 0xc7, 0x36, - 0x3f, 0xcc, 0x31, 0xdb, 0x5c, 0x8d, 0x7a, 0xf2, 0x28, 0x36, 0x76, 0x61, 0x42, 0x4d, 0x6c, 0x64, - 0x37, 0x67, 0x49, 0xff, 0xcd, 0xdd, 0x3b, 0x29, 0x4d, 0x81, 0x33, 0xe5, 0xfa, 0xf0, 0x0d, 0xde, - 0xff, 0xcc, 0xc1, 0x33, 0xc9, 0x0a, 0x7a, 0xe6, 0x7e, 0x38, 0x31, 0x73, 0x3f, 0x60, 0xce, 0xdc, - 0x07, 0x07, 0x33, 0xcf, 0xf5, 0xa9, 0xf6, 0x43, 0x33, 0xb1, 0xd1, 0x92, 0xea, 0xf7, 0x11, 0x26, - 0xdd, 0x5c, 0xb2, 0x8f, 0x1e, 0x1c, 0xcc, 0xbc, 0xd0, 0xa7, 0x8d, 0x29, 0x8d, 0xfb, 0x3e, 0x28, - 0x86, 0xc4, 0x89, 0x02, 0x7f, 0xba, 0x90, 0x54, 0x03, 0x98, 0x95, 0x62, 0x01, 0xb5, 0xff, 0xb4, - 0x94, 0xee, 0xec, 0x25, 0x7e, 0x76, 0x12, 0x84, 0xc8, 0x83, 0x11, 0x66, 0x8d, 0xf1, 0x61, 0x7d, - 0xf3, 0x64, 0x43, 0x80, 0xce, 0x5e, 0x45, 0xba, 0x52, 0xa2, 0x5f, 0x8d, 0x16, 0x61, 0xc6, 0x02, - 0xed, 0x43, 0xc9, 0x95, 0x46, 0x52, 0x2e, 0x8b, 0xe3, 0x04, 0x61, 0x22, 0x69, 0x8e, 0xe3, 0x54, - 0x85, 0x28, 0xcb, 0x4a, 0x71, 0x43, 0x04, 0xf2, 0x75, 0x2f, 0x16, 0x9f, 0xf5, 0x84, 0x66, 0xf0, - 0x92, 0x67, 0x34, 0x71, 0xf4, 0xf0, 0x60, 0x26, 0xbf, 0xe4, 0xc5, 0x98, 0xd2, 0x47, 0xbf, 0x6a, - 0xc1, 0x58, 0xe4, 0x36, 0x37, 0xc2, 0x60, 0xcf, 0xab, 0x92, 0x50, 0x2c, 0x82, 0x27, 0x9c, 0x56, - 0x9b, 0x0b, 0xab, 0x92, 0xa0, 0xe6, 0xcb, 0xb7, 0x25, 0x1a, 0x82, 0x4d, 0xbe, 0xd4, 0x38, 0x7c, - 0x46, 0xb4, 0x7d, 0x91, 0xb8, 0x5e, 0x44, 0x97, 0x4c, 0x61, 0x0b, 0xb3, 0x91, 0x72, 0x62, 0xa3, - 0x60, 0xb1, 0xed, 0xee, 0xd2, 0xf9, 0xa6, 0x05, 0x7a, 0xee, 0xf0, 0x60, 0xe6, 0x99, 0x85, 0xde, - 0x3c, 0x71, 0x3f, 0x61, 0x58, 0x87, 0xb5, 0xda, 0x8d, 0x06, 0x26, 0xf7, 0xda, 0x84, 0xed, 0x74, - 0x33, 0xe8, 0xb0, 0x0d, 0x4d, 0x30, 0xd5, 0x61, 0x06, 0x04, 0x9b, 0x7c, 0xd1, 0x3d, 0x28, 0x36, - 0x9d, 0x38, 0xf4, 0xf6, 0xc5, 0xf6, 0xf6, 0x84, 0x66, 0xda, 0x2a, 0xa3, 0xa5, 0x99, 0x03, 0x9d, - 0x93, 0xbc, 0x10, 0x0b, 0x46, 0xa8, 0x09, 0x85, 0x26, 0x09, 0xeb, 0x64, 0xba, 0x94, 0xc5, 0x51, - 0xde, 0x2a, 0x25, 0xa5, 0x19, 0x96, 0xe9, 0xa2, 0xc6, 0xca, 0x30, 0xe7, 0x82, 0x3e, 0x06, 0xa5, - 0x88, 0x34, 0x88, 0x1b, 0x07, 0xe1, 0x74, 0x99, 0x71, 0xfc, 0x89, 0x01, 0x97, 0x68, 0x67, 0x9b, - 0x34, 0x36, 0x45, 0x55, 0x3e, 0xc1, 0xe4, 0x3f, 0xac, 0x48, 0xda, 0xff, 0xd5, 0x02, 0x94, 0xd4, - 0x30, 0x8f, 0xc0, 0x30, 0xb8, 0x97, 0x34, 0x0c, 0x56, 0xb2, 0x5c, 0xbe, 0xfa, 0xd8, 0x06, 0xdf, - 0x29, 0x41, 0x4a, 0x37, 0xaf, 0x91, 0x28, 0x26, 0xd5, 0xf7, 0xf4, 0xe9, 0x7b, 0xfa, 0xf4, 0x3d, - 0x7d, 0xaa, 0xf4, 0xe9, 0x76, 0x4a, 0x9f, 0xbe, 0x69, 0xcc, 0x7a, 0x7d, 0xc7, 0xf4, 0x09, 0x75, - 0x09, 0x65, 0x4a, 0x60, 0x20, 0x50, 0x4d, 0x70, 0x63, 0x73, 0x7d, 0xad, 0xa7, 0x02, 0xfd, 0x44, - 0x52, 0x81, 0x9e, 0x94, 0xc5, 0x23, 0x57, 0x99, 0x87, 0xf9, 0xb4, 0xca, 0x64, 0xd7, 0x00, 0x57, - 0x00, 0xea, 0xc1, 0x16, 0x69, 0xb6, 0x1a, 0x4e, 0xcc, 0x4d, 0xe0, 0x92, 0xde, 0x3a, 0x2c, 0x29, - 0x08, 0x36, 0xb0, 0xd0, 0x5f, 0xb3, 0x00, 0xea, 0xf2, 0xd3, 0x48, 0x75, 0x78, 0x2b, 0x4b, 0x75, - 0xa8, 0x3f, 0xbc, 0x96, 0x45, 0x31, 0xc4, 0x06, 0x73, 0xf4, 0x19, 0x0b, 0x4a, 0xb1, 0x14, 0x9f, - 0x2b, 0x88, 0xad, 0x2c, 0x25, 0x91, 0x8d, 0xd6, 0x2b, 0x83, 0xea, 0x12, 0xc5, 0x17, 0xfd, 0x9a, - 0x05, 0x10, 0x75, 0x7c, 0x77, 0x23, 0x68, 0x78, 0x6e, 0x47, 0xe8, 0x8d, 0xdb, 0x99, 0x6e, 0x6f, - 0x14, 0xf5, 0xca, 0x24, 0xed, 0x0d, 0xfd, 0x1f, 0x1b, 0x9c, 0xed, 0x6f, 0x26, 0x4f, 0x27, 0xd4, - 0xbe, 0x88, 0x7d, 0x32, 0x57, 0x9a, 0xf5, 0x91, 0x38, 0xba, 0xcb, 0xf4, 0x93, 0xa9, 0x4d, 0x83, - 0xfe, 0x64, 0xaa, 0x28, 0xc2, 0x06, 0x73, 0xfb, 0xd3, 0x16, 0x4c, 0xf7, 0x6b, 0x1d, 0x22, 0xf0, - 0x5c, 0x2b, 0x24, 0x6c, 0x0e, 0xa9, 0x43, 0xf7, 0x75, 0x7f, 0x91, 0x34, 0x08, 0x3b, 0xe7, 0xe1, - 0x03, 0xf4, 0x45, 0xc1, 0xe1, 0xb9, 0x8d, 0xfe, 0xa8, 0xf8, 0x61, 0x74, 0xec, 0xdf, 0xca, 0x25, - 0x0e, 0x3b, 0x8c, 0x0f, 0x8d, 0xbe, 0x6e, 0x75, 0x59, 0x11, 0x3f, 0x7b, 0x1a, 0x23, 0x8a, 0xd9, - 0x1b, 0xea, 0xec, 0xbd, 0x3f, 0xce, 0x63, 0x3c, 0xdc, 0xb3, 0xff, 0xed, 0x08, 0x3c, 0x44, 0x32, - 0x75, 0x7c, 0x63, 0xf5, 0x3b, 0xbe, 0x19, 0xfe, 0x44, 0xe8, 0x0b, 0x16, 0x14, 0x1b, 0x54, 0xa1, - 0x45, 0xd3, 0x79, 0x36, 0x48, 0xab, 0xa7, 0xd5, 0xf7, 0x5c, 0x6f, 0x46, 0xfc, 0x80, 0x59, 0x6d, - 0x65, 0x79, 0x21, 0x16, 0x32, 0xa0, 0x6f, 0x58, 0x30, 0xe6, 0xf8, 0x7e, 0x10, 0x8b, 0x1b, 0x4f, - 0x7e, 0x63, 0xe8, 0x9d, 0x9a, 0x4c, 0xf3, 0x9a, 0x17, 0x17, 0x4c, 0xdd, 0x66, 0x1a, 0x10, 0x6c, - 0x8a, 0x84, 0x66, 0x01, 0x6a, 0x9e, 0xef, 0x34, 0xbc, 0x77, 0xa8, 0x61, 0x56, 0x60, 0xd7, 0x0b, - 0x4c, 0x47, 0x5c, 0x53, 0xa5, 0xd8, 0xc0, 0xb8, 0xf8, 0x57, 0x61, 0xcc, 0x68, 0x79, 0x8f, 0x73, - 0xf1, 0xf3, 0xe6, 0xb9, 0x78, 0xd9, 0x38, 0xce, 0xbe, 0xf8, 0x26, 0x9c, 0x4d, 0x0b, 0x38, 0x4c, - 0x7d, 0xfb, 0xb7, 0x8b, 0x30, 0x93, 0x6e, 0x7c, 0xd8, 0xa4, 0xa2, 0xbd, 0x67, 0xd0, 0xbe, 0x67, - 0xd0, 0xbe, 0x67, 0xd0, 0xca, 0x3f, 0xf6, 0xb7, 0x0b, 0x30, 0x65, 0x4e, 0x14, 0x2e, 0xdd, 0x8f, - 0xc3, 0x68, 0x48, 0x5a, 0xc1, 0x2d, 0xbc, 0x22, 0x34, 0xae, 0xf6, 0x14, 0xe2, 0xc5, 0x58, 0xc2, - 0xa9, 0x66, 0x6e, 0x39, 0xf1, 0x8e, 0x50, 0xb9, 0x4a, 0x33, 0x6f, 0x38, 0xf1, 0x0e, 0x66, 0x10, - 0xf4, 0x26, 0x4c, 0xc6, 0x4e, 0x58, 0x27, 0x31, 0x26, 0x7b, 0xac, 0x13, 0xc4, 0xe9, 0xe0, 0xd3, - 0x02, 0x77, 0x72, 0x2b, 0x01, 0xc5, 0x29, 0x6c, 0x74, 0x0f, 0x46, 0x76, 0x48, 0xa3, 0x29, 0x2c, - 0xee, 0xcd, 0xec, 0x34, 0x22, 0x6b, 0xeb, 0x75, 0xd2, 0x68, 0xf2, 0xf9, 0x4a, 0x7f, 0x61, 0xc6, - 0x8a, 0x7e, 0x9d, 0xf2, 0x6e, 0x3b, 0x8a, 0x83, 0xa6, 0xf7, 0x8e, 0xb4, 0xc3, 0x7f, 0x36, 0x63, - 0xc6, 0x37, 0x25, 0x7d, 0x7e, 0x07, 0xa4, 0xfe, 0x62, 0xcd, 0x99, 0xc9, 0x51, 0xf5, 0x42, 0x66, - 0x57, 0x77, 0xa6, 0xe1, 0x54, 0xe4, 0x58, 0x94, 0xf4, 0xb9, 0x1c, 0xea, 0x2f, 0xd6, 0x9c, 0x51, - 0x07, 0x8a, 0xad, 0x46, 0xbb, 0xee, 0xf9, 0xd3, 0x63, 0x4c, 0x86, 0x5b, 0x19, 0xcb, 0xb0, 0xc1, - 0x88, 0xf3, 0xdd, 0x10, 0xff, 0x8d, 0x05, 0x43, 0xf4, 0x22, 0x14, 0xdc, 0x1d, 0x27, 0x8c, 0xa7, - 0xc7, 0xd9, 0xa0, 0x51, 0xa7, 0x17, 0x0b, 0xb4, 0x10, 0x73, 0x98, 0xfd, 0xf7, 0x72, 0x49, 0xeb, - 0x21, 0xd9, 0x30, 0x3e, 0x9c, 0xdd, 0x76, 0x18, 0xc9, 0x7d, 0x87, 0x31, 0x9c, 0x59, 0x31, 0x96, - 0x70, 0xf4, 0x69, 0x0b, 0x46, 0xef, 0x46, 0x81, 0xef, 0x93, 0x58, 0x68, 0xea, 0xdb, 0x19, 0xb7, - 0xf5, 0x06, 0xa7, 0xae, 0x65, 0x10, 0x05, 0x58, 0xf2, 0xa5, 0xe2, 0x92, 0x7d, 0xb7, 0xd1, 0xae, - 0xca, 0xeb, 0x2a, 0x85, 0x7a, 0x95, 0x17, 0x63, 0x09, 0xa7, 0xa8, 0x9e, 0xcf, 0x51, 0x47, 0x92, - 0xa8, 0xcb, 0xbe, 0x40, 0x15, 0x70, 0xfb, 0x77, 0x0b, 0x70, 0xa1, 0xe7, 0xe8, 0xa7, 0xeb, 0x3a, - 0x5b, 0x39, 0xaf, 0x79, 0x0d, 0x22, 0xfd, 0xb3, 0xd8, 0xba, 0x7e, 0x5b, 0x95, 0x62, 0x03, 0x03, - 0xfd, 0x32, 0x40, 0xcb, 0x09, 0x9d, 0x26, 0x11, 0xeb, 0x59, 0xfe, 0xe4, 0xcb, 0x27, 0x95, 0x63, - 0x43, 0xd2, 0xd4, 0x76, 0xbd, 0x2a, 0x8a, 0xb0, 0xc1, 0x12, 0x7d, 0x10, 0xc6, 0x42, 0xd2, 0x20, - 0x4e, 0xc4, 0x1c, 0x18, 0xd2, 0xde, 0x58, 0x58, 0x83, 0xb0, 0x89, 0x87, 0xde, 0x07, 0x45, 0xd6, - 0x0a, 0x79, 0x3d, 0xa1, 0x4c, 0x31, 0xd6, 0xce, 0x08, 0x0b, 0x28, 0xfa, 0xb2, 0x05, 0x93, 0x35, - 0xaf, 0x41, 0x34, 0x77, 0xe1, 0x3b, 0xb5, 0x7e, 0xf2, 0x46, 0x5e, 0x33, 0xe9, 0x6a, 0x15, 0x98, - 0x28, 0x8e, 0x70, 0x8a, 0x3d, 0xfd, 0xcc, 0x7b, 0x24, 0x64, 0xba, 0xb3, 0x98, 0xfc, 0xcc, 0xb7, - 0x79, 0x31, 0x96, 0x70, 0x34, 0x0f, 0x67, 0x5a, 0x4e, 0x14, 0x2d, 0x84, 0xa4, 0x4a, 0xfc, 0xd8, - 0x73, 0x1a, 0xdc, 0xb3, 0xa9, 0xa4, 0x3d, 0x1b, 0x36, 0x92, 0x60, 0x9c, 0xc6, 0x47, 0x1f, 0x81, - 0x67, 0xbc, 0xba, 0x1f, 0x84, 0x64, 0xd5, 0x8b, 0x22, 0xcf, 0xaf, 0xeb, 0x61, 0xc0, 0x54, 0x61, - 0xa9, 0x32, 0x23, 0x48, 0x3d, 0xb3, 0xdc, 0x1b, 0x0d, 0xf7, 0xab, 0x8f, 0x5e, 0x86, 0x52, 0xb4, - 0xeb, 0xb5, 0x16, 0xc2, 0x6a, 0xc4, 0x8e, 0x1e, 0x4a, 0x7a, 0xb7, 0xbb, 0x29, 0xca, 0xb1, 0xc2, - 0xb0, 0x7f, 0x23, 0x97, 0xdc, 0xbf, 0x99, 0xf3, 0x07, 0x45, 0x74, 0x96, 0xc4, 0xb7, 0x9d, 0x50, - 0x6e, 0x32, 0x4f, 0xe8, 0x1b, 0x25, 0xe8, 0xde, 0x76, 0x42, 0x73, 0xbe, 0x31, 0x06, 0x58, 0x72, - 0x42, 0x77, 0x61, 0x24, 0x6e, 0x38, 0x19, 0x39, 0x53, 0x1a, 0x1c, 0xf5, 0x2d, 0xfe, 0xca, 0x7c, - 0x84, 0x19, 0x0f, 0xf4, 0x3c, 0xb5, 0x4f, 0xb7, 0xf9, 0xee, 0xa4, 0x2c, 0x4d, 0xca, 0xed, 0x08, - 0xb3, 0x52, 0xfb, 0x7f, 0x17, 0x7b, 0xa8, 0x3c, 0xb5, 0x88, 0xa0, 0x2b, 0x00, 0x74, 0xab, 0xb3, - 0x11, 0x92, 0x9a, 0xb7, 0x2f, 0x16, 0x71, 0x35, 0xad, 0xd6, 0x14, 0x04, 0x1b, 0x58, 0xb2, 0xce, - 0x66, 0xbb, 0x46, 0xeb, 0xe4, 0xba, 0xeb, 0x70, 0x08, 0x36, 0xb0, 0xd0, 0x6b, 0x50, 0xf4, 0x9a, - 0x4e, 0x9d, 0x48, 0x31, 0x9f, 0xa7, 0xf3, 0x69, 0x99, 0x95, 0x3c, 0x38, 0x98, 0x99, 0x54, 0x02, - 0xb1, 0x22, 0x2c, 0x70, 0xd1, 0x6f, 0x59, 0x30, 0xee, 0x06, 0xcd, 0x66, 0xe0, 0xf3, 0x0d, 0x82, - 0xd8, 0xed, 0xdc, 0x3d, 0xad, 0x25, 0x76, 0x76, 0xc1, 0x60, 0xc6, 0xb7, 0x3b, 0xca, 0xeb, 0xd3, - 0x04, 0xe1, 0x84, 0x54, 0xe6, 0xb4, 0x2b, 0x1c, 0x31, 0xed, 0xfe, 0x99, 0x05, 0x53, 0xbc, 0xae, - 0xb1, 0x6f, 0x11, 0x0e, 0x8e, 0xc1, 0x29, 0x37, 0xab, 0x6b, 0x2b, 0xf7, 0xac, 0x10, 0x73, 0xaa, - 0x0b, 0x8e, 0xbb, 0x85, 0x44, 0x4b, 0x30, 0x55, 0x0b, 0x42, 0x97, 0x98, 0x1d, 0x21, 0x74, 0x86, - 0x22, 0x74, 0x2d, 0x8d, 0x80, 0xbb, 0xeb, 0xa0, 0xdb, 0xf0, 0xb4, 0x51, 0x68, 0xf6, 0x03, 0x57, - 0x1b, 0x97, 0x04, 0xb5, 0xa7, 0xaf, 0xf5, 0xc4, 0xc2, 0x7d, 0x6a, 0x5f, 0xfc, 0x30, 0x4c, 0x75, - 0x7d, 0xbf, 0xa1, 0x76, 0x93, 0x8b, 0xf0, 0x74, 0xef, 0x9e, 0x1a, 0x6a, 0x4f, 0xf9, 0x4f, 0x52, - 0x37, 0xfb, 0x86, 0xe5, 0x32, 0xc0, 0xf9, 0x84, 0x03, 0x79, 0xe2, 0xef, 0x09, 0xc5, 0x71, 0xed, - 0x64, 0x23, 0xe2, 0xaa, 0xbf, 0xc7, 0x3f, 0x34, 0xdb, 0x84, 0x5d, 0xf5, 0xf7, 0x30, 0xa5, 0x8d, - 0xbe, 0x6a, 0x25, 0x16, 0x66, 0x7e, 0xaa, 0xf1, 0xf1, 0x53, 0x31, 0xd5, 0x06, 0x5e, 0xab, 0xed, - 0x3f, 0xc8, 0xc1, 0xe5, 0xa3, 0x88, 0x0c, 0xd0, 0x7d, 0x2f, 0x42, 0x31, 0x8a, 0x43, 0xcf, 0xaf, - 0x8b, 0x99, 0x38, 0x46, 0x67, 0xe1, 0x26, 0x2b, 0xf9, 0x04, 0x16, 0x20, 0xf4, 0x6b, 0x16, 0xe4, - 0x9b, 0x4e, 0x4b, 0xb4, 0xbc, 0x7e, 0xba, 0x2d, 0x9f, 0x5d, 0x75, 0x5a, 0xfc, 0x2b, 0x8c, 0x09, - 0x79, 0xf3, 0xab, 0x4e, 0x0b, 0x53, 0x01, 0xd0, 0x0c, 0x14, 0x9c, 0x30, 0x74, 0x3a, 0x4c, 0xaf, - 0x95, 0xf9, 0x11, 0xfc, 0x3c, 0x2d, 0xc0, 0xbc, 0xfc, 0xe2, 0x87, 0xa0, 0x24, 0xab, 0x0f, 0x35, - 0x06, 0xff, 0x66, 0x31, 0xe1, 0xa4, 0xb4, 0x29, 0xfd, 0xe2, 0xf8, 0x0e, 0xd7, 0xca, 0xda, 0x2f, - 0x8e, 0x7b, 0x99, 0x6a, 0x57, 0x17, 0xbe, 0xa9, 0x15, 0xec, 0xd0, 0xe7, 0x2d, 0xe6, 0x15, 0x2f, - 0x9d, 0xb7, 0x84, 0xbd, 0x7c, 0x3a, 0x4e, 0xfa, 0xa6, 0xaf, 0xbd, 0x2c, 0xc4, 0x26, 0x77, 0xaa, - 0xac, 0x5b, 0xdc, 0xbf, 0x33, 0x6d, 0x35, 0x4b, 0xbf, 0x79, 0x09, 0x47, 0xfb, 0x3d, 0x0e, 0xd1, - 0x33, 0xf0, 0xac, 0x3e, 0xfa, 0xd8, 0x1c, 0x7d, 0xc3, 0x82, 0x29, 0x6e, 0x1b, 0x2d, 0x7a, 0xb5, - 0x1a, 0x09, 0x89, 0xef, 0x12, 0x69, 0x5d, 0xde, 0x39, 0x99, 0x04, 0xf2, 0x68, 0x61, 0x39, 0x4d, - 0x5e, 0x6b, 0xf1, 0x2e, 0x10, 0xee, 0x16, 0x06, 0x55, 0x61, 0xc4, 0xf3, 0x6b, 0x81, 0x58, 0xbb, - 0x2a, 0x27, 0x13, 0x6a, 0xd9, 0xaf, 0x05, 0x7a, 0x3e, 0xd3, 0x7f, 0x98, 0x51, 0x47, 0x2b, 0x70, - 0x3e, 0x14, 0x1b, 0xfc, 0xeb, 0x5e, 0x44, 0x77, 0x69, 0x2b, 0x5e, 0xd3, 0x8b, 0xd9, 0xba, 0x93, - 0xaf, 0x4c, 0x1f, 0x1e, 0xcc, 0x9c, 0xc7, 0x3d, 0xe0, 0xb8, 0x67, 0x2d, 0xfb, 0x07, 0xe5, 0xe4, - 0x29, 0x06, 0xbf, 0x8a, 0xf8, 0x45, 0x28, 0x87, 0xca, 0xbd, 0xdf, 0xca, 0xe2, 0x2a, 0x5d, 0xf6, - 0xb1, 0xf0, 0x01, 0x53, 0x07, 0xcc, 0xda, 0x91, 0x5f, 0x73, 0xa4, 0xb6, 0x22, 0xfd, 0xf2, 0x62, - 0x5a, 0x64, 0x30, 0xbe, 0x04, 0x57, 0x7d, 0x7c, 0xde, 0xf1, 0x5d, 0xcc, 0x78, 0xa0, 0x10, 0x8a, - 0x3b, 0xc4, 0x69, 0xc4, 0x3b, 0xd9, 0x9c, 0xf4, 0x5d, 0x67, 0xb4, 0xd2, 0x9e, 0x6e, 0xbc, 0x14, - 0x0b, 0x4e, 0x68, 0x1f, 0x46, 0x77, 0xf8, 0x47, 0x10, 0xe6, 0xdb, 0xea, 0x49, 0x3b, 0x37, 0xf1, - 0x65, 0xf5, 0xfc, 0x15, 0x05, 0x58, 0xb2, 0x63, 0xb7, 0x60, 0xc6, 0x1d, 0x13, 0x9f, 0x3e, 0xd9, - 0x39, 0xf9, 0x0d, 0x7c, 0xc1, 0x84, 0x3e, 0x09, 0xe3, 0x21, 0x71, 0x03, 0xdf, 0xf5, 0x1a, 0xa4, - 0x3a, 0x2f, 0x4f, 0xf1, 0x86, 0x71, 0xaf, 0x3b, 0x4b, 0x4d, 0x50, 0x6c, 0xd0, 0xc0, 0x09, 0x8a, - 0xe8, 0x73, 0x16, 0x4c, 0x2a, 0x9f, 0x60, 0xfa, 0x41, 0x88, 0x38, 0x07, 0x5b, 0xc9, 0xc8, 0x03, - 0x99, 0xd1, 0xac, 0x20, 0xba, 0x09, 0x4d, 0x96, 0xe1, 0x14, 0x5f, 0xf4, 0x36, 0x40, 0xb0, 0xcd, - 0xee, 0xb9, 0x68, 0x53, 0x4b, 0x43, 0x37, 0x75, 0x92, 0xfb, 0x88, 0x4a, 0x0a, 0xd8, 0xa0, 0x86, - 0x6e, 0x02, 0xf0, 0x69, 0xb3, 0xd5, 0x69, 0x11, 0xb6, 0x33, 0xd4, 0xfe, 0x91, 0xb0, 0xa9, 0x20, - 0x0f, 0x0e, 0x66, 0xba, 0xcf, 0x30, 0x98, 0x7f, 0xa4, 0x51, 0x1d, 0xfd, 0x3c, 0x8c, 0x46, 0xed, - 0x66, 0xd3, 0x51, 0x47, 0x66, 0x19, 0x7a, 0x9d, 0x72, 0xba, 0x7a, 0x6c, 0x8a, 0x02, 0x2c, 0x39, - 0xa2, 0xbb, 0x54, 0xb1, 0x45, 0xe2, 0x70, 0x85, 0xcd, 0x22, 0xbe, 0x36, 0x8f, 0xb1, 0x36, 0x7d, - 0x48, 0xd4, 0x3b, 0x8f, 0x7b, 0xe0, 0x3c, 0x38, 0x98, 0x79, 0x3a, 0x59, 0xbe, 0x12, 0x70, 0xb6, - 0xb8, 0x27, 0x4d, 0xdb, 0x4f, 0x5e, 0xb4, 0x0b, 0x09, 0x5e, 0x83, 0x71, 0xb2, 0x1f, 0x93, 0xd0, - 0x77, 0x1a, 0xb7, 0xf0, 0x8a, 0x3c, 0xd0, 0x61, 0x03, 0xed, 0xaa, 0x51, 0x8e, 0x13, 0x58, 0xc8, - 0x56, 0x1b, 0xb9, 0x1c, 0xc3, 0x07, 0xbd, 0x91, 0x93, 0xdb, 0x36, 0xfb, 0xff, 0xe5, 0x12, 0xd6, - 0xc7, 0x56, 0x48, 0x08, 0x0a, 0xa0, 0xe0, 0x07, 0x55, 0xa5, 0x60, 0x6f, 0x64, 0xa3, 0x60, 0xd7, - 0x82, 0xaa, 0x11, 0xe3, 0x46, 0xff, 0x45, 0x98, 0xf3, 0x61, 0x41, 0x40, 0x32, 0x5a, 0x8a, 0x01, - 0x84, 0x4d, 0x9d, 0x25, 0x67, 0x15, 0x04, 0xb4, 0x6e, 0x32, 0xc2, 0x49, 0xbe, 0x68, 0x17, 0x0a, - 0x3b, 0x41, 0x14, 0x4b, 0x4b, 0xfb, 0x84, 0x46, 0xfd, 0xf5, 0x20, 0x8a, 0xd9, 0x72, 0xa9, 0x9a, - 0x4d, 0x4b, 0x22, 0xcc, 0x79, 0xd8, 0xff, 0xcd, 0x4a, 0x1c, 0xdf, 0xdd, 0x71, 0x62, 0x77, 0xe7, - 0xea, 0x1e, 0xf1, 0xe9, 0xdc, 0x31, 0xbd, 0x8a, 0xff, 0x4a, 0xca, 0xab, 0xf8, 0xfd, 0xfd, 0x82, - 0x8e, 0xef, 0x53, 0x0a, 0xb3, 0x8c, 0x84, 0xe1, 0x61, 0xfc, 0x29, 0x0b, 0xc6, 0x0c, 0xf1, 0xc4, - 0xe2, 0x95, 0xa1, 0x6b, 0xba, 0xbe, 0x66, 0xd4, 0x85, 0xd8, 0x64, 0x69, 0x7f, 0xd5, 0x82, 0xd1, - 0x8a, 0xe3, 0xee, 0x06, 0xb5, 0x1a, 0x7a, 0x19, 0x4a, 0xd5, 0xb6, 0x88, 0xbc, 0xe0, 0xed, 0x53, - 0xe7, 0x45, 0x8b, 0xa2, 0x1c, 0x2b, 0x0c, 0x3a, 0x86, 0x6b, 0x0e, 0x73, 0x6b, 0xc9, 0x31, 0x33, - 0x82, 0x8d, 0xe1, 0x6b, 0xac, 0x04, 0x0b, 0x08, 0xfa, 0x20, 0x8c, 0x35, 0x9d, 0x7d, 0x59, 0x39, - 0x7d, 0x76, 0xb8, 0xaa, 0x41, 0xd8, 0xc4, 0xb3, 0xff, 0xb5, 0x05, 0xd3, 0x15, 0x27, 0xf2, 0xdc, - 0xf9, 0x76, 0xbc, 0x53, 0xf1, 0xe2, 0xed, 0xb6, 0xbb, 0x4b, 0x62, 0x1e, 0x95, 0x40, 0xa5, 0x6c, - 0x47, 0x74, 0x2a, 0xa9, 0x2d, 0x8c, 0x92, 0xf2, 0x96, 0x28, 0xc7, 0x0a, 0x03, 0xbd, 0x03, 0x63, - 0x2d, 0x27, 0x8a, 0xee, 0x07, 0x61, 0x15, 0x93, 0x5a, 0x36, 0x31, 0x41, 0x9b, 0xc4, 0x0d, 0x49, - 0x8c, 0x49, 0x4d, 0x5c, 0xf7, 0x68, 0xfa, 0xd8, 0x64, 0x66, 0xff, 0xab, 0x32, 0x8c, 0x8a, 0xbb, - 0xaa, 0x81, 0x63, 0x2d, 0xe4, 0xe6, 0x2c, 0xd7, 0x77, 0x73, 0x16, 0x41, 0xd1, 0x65, 0x91, 0xe9, - 0xc2, 0xfa, 0xb8, 0x99, 0xc9, 0xe5, 0x26, 0x0f, 0x76, 0xd7, 0x62, 0xf1, 0xff, 0x58, 0xb0, 0x42, - 0x5f, 0xb1, 0xe0, 0x8c, 0x1b, 0xf8, 0x3e, 0x71, 0xf5, 0xd2, 0x38, 0x92, 0x85, 0xbb, 0xc2, 0x42, - 0x92, 0xa8, 0x3e, 0x38, 0x4d, 0x01, 0x70, 0x9a, 0x3d, 0x7a, 0x03, 0x26, 0x78, 0x9f, 0xdd, 0x4e, - 0x9c, 0x1a, 0xe9, 0x90, 0x42, 0x13, 0x88, 0x93, 0xb8, 0x68, 0x96, 0x9f, 0xbe, 0x89, 0xe0, 0xbd, - 0xa2, 0x3e, 0x85, 0x37, 0xc2, 0xf6, 0x0c, 0x0c, 0x14, 0x02, 0x0a, 0x49, 0x2d, 0x24, 0xd1, 0x8e, - 0xb8, 0xcb, 0x63, 0xcb, 0xf2, 0xe8, 0xf1, 0x1c, 0xfc, 0x71, 0x17, 0x25, 0xdc, 0x83, 0x3a, 0xda, - 0x15, 0x7b, 0x83, 0x52, 0x16, 0x5a, 0x41, 0x7c, 0xe6, 0xbe, 0x5b, 0x84, 0x19, 0x28, 0x44, 0x3b, - 0x4e, 0x58, 0x65, 0xe6, 0x40, 0x9e, 0x6f, 0xa2, 0x37, 0x69, 0x01, 0xe6, 0xe5, 0x68, 0x11, 0xce, - 0xa6, 0x02, 0x22, 0x23, 0xb6, 0xe0, 0x97, 0x2a, 0xd3, 0x82, 0xdc, 0xd9, 0x54, 0x28, 0x65, 0x84, - 0xbb, 0x6a, 0x98, 0xfb, 0xc6, 0xb1, 0x23, 0xf6, 0x8d, 0x1d, 0xe5, 0x31, 0x32, 0xce, 0x34, 0xfe, - 0x5b, 0x99, 0x74, 0xc0, 0x40, 0xee, 0x21, 0x5f, 0x4c, 0xb9, 0x87, 0x4c, 0x30, 0x01, 0x6e, 0x67, - 0x23, 0xc0, 0xf0, 0xbe, 0x20, 0x8f, 0xd3, 0xb7, 0xe3, 0x07, 0x16, 0xc8, 0xef, 0xba, 0xe0, 0xb8, - 0x3b, 0x84, 0x0e, 0x19, 0xf4, 0x26, 0x4c, 0xaa, 0x9d, 0xd7, 0x42, 0xd0, 0xf6, 0xb9, 0x5b, 0x47, - 0x5e, 0xdf, 0xb0, 0xe0, 0x04, 0x14, 0xa7, 0xb0, 0xd1, 0x1c, 0x94, 0x69, 0x3f, 0xf1, 0xaa, 0x7c, - 0xf5, 0x50, 0xbb, 0xbb, 0xf9, 0x8d, 0x65, 0x51, 0x4b, 0xe3, 0xa0, 0x00, 0xa6, 0x1a, 0x4e, 0x14, - 0x33, 0x09, 0xe8, 0x46, 0xec, 0x98, 0xe1, 0x35, 0x2c, 0x1e, 0x7c, 0x25, 0x4d, 0x08, 0x77, 0xd3, - 0xb6, 0xbf, 0x37, 0x02, 0x13, 0x09, 0xcd, 0x38, 0xe4, 0xb2, 0xf3, 0x32, 0x94, 0xe4, 0x4a, 0x20, - 0x54, 0xb9, 0xc2, 0x56, 0xcb, 0x85, 0xc2, 0xa0, 0xcb, 0xe4, 0x36, 0x71, 0x42, 0x12, 0xb2, 0x50, - 0xd3, 0xf4, 0x32, 0x59, 0xd1, 0x20, 0x6c, 0xe2, 0x31, 0xa5, 0x1c, 0x37, 0xa2, 0x85, 0x86, 0x47, - 0xfc, 0x98, 0x8b, 0x99, 0x8d, 0x52, 0xde, 0x5a, 0xd9, 0x34, 0x89, 0x6a, 0xa5, 0x9c, 0x02, 0xe0, - 0x34, 0x7b, 0xf4, 0x59, 0x0b, 0x26, 0x9c, 0xfb, 0x91, 0x4e, 0x9f, 0x22, 0x1c, 0x41, 0x4e, 0xb8, - 0x48, 0x25, 0x32, 0xb2, 0x54, 0xa6, 0xa8, 0x7a, 0x4f, 0x14, 0xe1, 0x24, 0x53, 0xf4, 0x75, 0x0b, - 0x10, 0xd9, 0x27, 0xae, 0x74, 0x55, 0x11, 0xb2, 0x14, 0xb3, 0xd8, 0xa0, 0x5c, 0xed, 0xa2, 0xcb, - 0xb5, 0x7a, 0x77, 0x39, 0xee, 0x21, 0x83, 0xfd, 0xcf, 0xf3, 0x6a, 0x42, 0x69, 0xef, 0x28, 0xc7, - 0x70, 0x12, 0xb6, 0x8e, 0xef, 0x24, 0xac, 0xaf, 0xf7, 0xba, 0x1c, 0x85, 0x93, 0x1e, 0xb5, 0xb9, - 0xc7, 0xe4, 0x51, 0xfb, 0x19, 0x4b, 0xdd, 0x0a, 0x73, 0x33, 0xfe, 0xed, 0x6c, 0x3d, 0xb3, 0x66, - 0xf9, 0xe5, 0x72, 0x4a, 0xbb, 0x27, 0x6f, 0x9c, 0xa9, 0x36, 0x35, 0xd0, 0x86, 0xd2, 0x86, 0xff, - 0x31, 0x0f, 0x63, 0xc6, 0x4a, 0xda, 0xd3, 0x2c, 0xb2, 0x9e, 0x30, 0xb3, 0x28, 0x37, 0x84, 0x59, - 0xf4, 0xcb, 0x50, 0x76, 0xa5, 0x96, 0xcf, 0x26, 0x57, 0x4f, 0x7a, 0xed, 0xd0, 0x8a, 0x5e, 0x15, - 0x61, 0xcd, 0x13, 0x2d, 0xc1, 0x94, 0x41, 0x46, 0xac, 0x10, 0x23, 0x6c, 0x85, 0x50, 0x07, 0xab, - 0xf3, 0x69, 0x04, 0xdc, 0x5d, 0x07, 0xbd, 0x4a, 0x77, 0x56, 0x9e, 0x68, 0x97, 0xf4, 0x9f, 0x64, - 0xe6, 0xfa, 0xfc, 0xc6, 0xb2, 0x2c, 0xc6, 0x26, 0x8e, 0xfd, 0x3d, 0x4b, 0x7d, 0xdc, 0x47, 0x10, - 0x76, 0x74, 0x37, 0x19, 0x76, 0x74, 0x35, 0x93, 0x6e, 0xee, 0x13, 0x6f, 0xb4, 0x06, 0xa3, 0x0b, - 0x41, 0xb3, 0xe9, 0xf8, 0x55, 0xf4, 0x63, 0x30, 0xea, 0xf2, 0x9f, 0xe2, 0xa8, 0x82, 0xdd, 0xed, - 0x08, 0x28, 0x96, 0x30, 0xf4, 0x3c, 0x8c, 0x38, 0x61, 0x5d, 0x1e, 0x4f, 0xb0, 0xeb, 0xf0, 0xf9, - 0xb0, 0x1e, 0x61, 0x56, 0x6a, 0x7f, 0x2d, 0x07, 0xb0, 0x10, 0x34, 0x5b, 0x4e, 0x48, 0xaa, 0x5b, - 0xc1, 0x7b, 0x77, 0x22, 0x7c, 0xd7, 0xfa, 0x05, 0x0b, 0x10, 0xed, 0x95, 0xc0, 0x27, 0x7e, 0xac, - 0xaf, 0xdb, 0xe6, 0xa0, 0xec, 0xca, 0x52, 0x61, 0x39, 0xe8, 0x39, 0x20, 0x01, 0x58, 0xe3, 0x0c, - 0xb0, 0x05, 0x7c, 0x51, 0x2a, 0xa8, 0x7c, 0xd2, 0x4d, 0x8b, 0xa9, 0x35, 0xa1, 0xaf, 0xec, 0xdf, - 0xcf, 0xc1, 0xd3, 0x7c, 0xcd, 0x59, 0x75, 0x7c, 0xa7, 0x4e, 0x9a, 0x54, 0xaa, 0x41, 0x2f, 0x50, - 0x5d, 0xba, 0xf7, 0xf0, 0xa4, 0x57, 0xd6, 0x49, 0x07, 0x27, 0x1f, 0x54, 0x7c, 0x18, 0x2d, 0xfb, - 0x5e, 0x8c, 0x19, 0x71, 0x14, 0x41, 0x49, 0x66, 0x5f, 0x13, 0xca, 0x26, 0x23, 0x46, 0x6a, 0xde, - 0x89, 0x85, 0x81, 0x60, 0xc5, 0x88, 0x5a, 0x66, 0x8d, 0xc0, 0xdd, 0xc5, 0xa4, 0x15, 0x30, 0xc5, - 0x62, 0x38, 0xc5, 0xac, 0x88, 0x72, 0xac, 0x30, 0xec, 0xdf, 0xb7, 0x20, 0xad, 0x72, 0xd9, 0x56, - 0x9e, 0x07, 0x5e, 0xa7, 0xb7, 0xf2, 0xc9, 0xb8, 0xea, 0x21, 0xe2, 0xc7, 0x7f, 0x0e, 0xc6, 0x9c, - 0x98, 0xae, 0x92, 0x7c, 0x5f, 0x99, 0x3f, 0xde, 0x71, 0xef, 0x6a, 0x50, 0xf5, 0x6a, 0x1e, 0xdb, - 0x4f, 0x9a, 0xe4, 0xec, 0x3f, 0x1f, 0x81, 0xa9, 0x2e, 0x57, 0x5a, 0xf4, 0x3a, 0x8c, 0xbb, 0x62, - 0x78, 0xb4, 0x30, 0xa9, 0x89, 0xc6, 0x18, 0x9e, 0x1a, 0x1a, 0x86, 0x13, 0x98, 0x03, 0x0c, 0xd0, - 0x65, 0x38, 0x17, 0xd2, 0x9d, 0x6c, 0x9b, 0xcc, 0xd7, 0x62, 0x12, 0x6e, 0x12, 0x37, 0xf0, 0xab, - 0x3c, 0x41, 0x40, 0xbe, 0xf2, 0xcc, 0xe1, 0xc1, 0xcc, 0x39, 0xdc, 0x0d, 0xc6, 0xbd, 0xea, 0xa0, - 0x16, 0x4c, 0x34, 0x4c, 0x23, 0x47, 0x58, 0xb8, 0xc7, 0xb2, 0x8f, 0xd4, 0x22, 0x98, 0x28, 0xc6, - 0x49, 0x06, 0x49, 0x4b, 0xa9, 0xf0, 0x98, 0x2c, 0xa5, 0x5f, 0xd1, 0x96, 0x12, 0xbf, 0x1b, 0xfc, - 0x68, 0xc6, 0xae, 0xd4, 0xa7, 0x6d, 0x2a, 0xbd, 0x05, 0x25, 0xe9, 0x39, 0x31, 0x90, 0xc7, 0x81, - 0x49, 0xa7, 0x8f, 0x46, 0x7b, 0x90, 0x83, 0x1e, 0x56, 0x36, 0x9d, 0x67, 0x7a, 0x49, 0x4b, 0xcc, - 0xb3, 0xe1, 0x96, 0x35, 0xb4, 0xcf, 0xbd, 0x46, 0xb8, 0x65, 0xfa, 0x91, 0xac, 0x77, 0x09, 0xda, - 0x91, 0x44, 0xb9, 0x30, 0x28, 0x67, 0x92, 0x2b, 0x00, 0xda, 0x12, 0x11, 0x0e, 0x93, 0xea, 0x3a, - 0x4c, 0x1b, 0x2c, 0xd8, 0xc0, 0xa2, 0x9b, 0x46, 0xcf, 0x8f, 0x62, 0xa7, 0xd1, 0xb8, 0xee, 0xf9, - 0xb1, 0x38, 0xfd, 0x52, 0xab, 0xd4, 0xb2, 0x06, 0x61, 0x13, 0xef, 0xe2, 0x87, 0x8c, 0xef, 0x32, - 0xcc, 0xf7, 0xdc, 0x81, 0x67, 0x97, 0xbc, 0x58, 0xb9, 0xf9, 0xaa, 0x71, 0x44, 0x0d, 0x0d, 0xe5, - 0x97, 0x6e, 0xf5, 0xf5, 0x4b, 0x37, 0xdc, 0x6c, 0x73, 0x49, 0xaf, 0xe0, 0xb4, 0x9b, 0xad, 0xfd, - 0x3a, 0x9c, 0x5f, 0xf2, 0xe2, 0x6b, 0x5e, 0x83, 0x0c, 0xc9, 0xc4, 0xfe, 0x6c, 0x01, 0xc6, 0xcd, - 0xb8, 0x89, 0x61, 0x5c, 0xeb, 0xbf, 0x44, 0x6d, 0x09, 0xd1, 0x3a, 0x4f, 0xdd, 0x73, 0xdc, 0x39, - 0x71, 0x10, 0x47, 0xef, 0x1e, 0x33, 0xcc, 0x09, 0xcd, 0x13, 0x9b, 0x02, 0xa0, 0xfb, 0x50, 0xa8, - 0x31, 0x37, 0xd0, 0x7c, 0x16, 0x37, 0xae, 0xbd, 0x7a, 0x54, 0x4f, 0x33, 0xee, 0x48, 0xca, 0xf9, - 0xd1, 0x15, 0x32, 0x4c, 0x06, 0x0f, 0x28, 0x45, 0xa5, 0xc2, 0x06, 0x14, 0x46, 0x3f, 0x55, 0x5f, - 0x38, 0x86, 0xaa, 0x4f, 0x28, 0xde, 0xe2, 0x63, 0x52, 0xbc, 0xcc, 0xa5, 0x37, 0xde, 0x61, 0xf6, - 0x9b, 0x70, 0xe8, 0x1c, 0x65, 0x9d, 0x60, 0xb8, 0xf4, 0x26, 0xc0, 0x38, 0x8d, 0x6f, 0x7f, 0x21, - 0x07, 0x93, 0x4b, 0x7e, 0x7b, 0x63, 0x69, 0xa3, 0xbd, 0xdd, 0xf0, 0xdc, 0x9b, 0xa4, 0x43, 0xf5, - 0xdb, 0x2e, 0xe9, 0x2c, 0x2f, 0x8a, 0x61, 0xa8, 0x3a, 0xfe, 0x26, 0x2d, 0xc4, 0x1c, 0x46, 0x67, - 0x74, 0xcd, 0xf3, 0xeb, 0x24, 0x6c, 0x85, 0x9e, 0x38, 0x18, 0x33, 0x66, 0xf4, 0x35, 0x0d, 0xc2, - 0x26, 0x1e, 0xa5, 0x1d, 0xdc, 0xf7, 0x49, 0x98, 0xb6, 0x06, 0xd7, 0x69, 0x21, 0xe6, 0x30, 0x8a, - 0x14, 0x87, 0xed, 0x28, 0x16, 0x5f, 0x54, 0x21, 0x6d, 0xd1, 0x42, 0xcc, 0x61, 0x74, 0xba, 0x44, - 0xed, 0x6d, 0x76, 0x2b, 0x9c, 0x72, 0xc1, 0xdc, 0xe4, 0xc5, 0x58, 0xc2, 0x29, 0xea, 0x2e, 0xe9, - 0x2c, 0xd2, 0xbd, 0x51, 0xca, 0x49, 0xfa, 0x26, 0x2f, 0xc6, 0x12, 0xce, 0xb2, 0x3a, 0x24, 0xbb, - 0xe3, 0x87, 0x2e, 0xab, 0x43, 0x52, 0xfc, 0x3e, 0xbb, 0xac, 0x6f, 0x5a, 0x30, 0x6e, 0xfa, 0x72, - 0xa0, 0x7a, 0xca, 0x50, 0x5c, 0xef, 0xca, 0xd0, 0xf3, 0xd3, 0xbd, 0x92, 0x46, 0xd7, 0xbd, 0x38, - 0x68, 0x45, 0xaf, 0x10, 0xbf, 0xee, 0xf9, 0x84, 0xdd, 0x1e, 0x72, 0x1f, 0x90, 0x84, 0xa3, 0xc8, - 0x42, 0x50, 0x25, 0xc7, 0xb0, 0x34, 0xed, 0x3b, 0x30, 0xd5, 0xe5, 0x19, 0x3f, 0xc0, 0xfa, 0x7c, - 0x64, 0xe0, 0x91, 0x8d, 0x61, 0x8c, 0x12, 0x5e, 0x6f, 0x71, 0x67, 0x8d, 0x05, 0x98, 0xe2, 0x36, - 0x04, 0xe5, 0xb4, 0xe9, 0xee, 0x90, 0xa6, 0x8a, 0x76, 0x60, 0xa7, 0xb0, 0xb7, 0xd3, 0x40, 0xdc, - 0x8d, 0x6f, 0x7f, 0xd1, 0x82, 0x89, 0x44, 0xb0, 0x42, 0x46, 0x96, 0x04, 0x9b, 0x69, 0x01, 0x73, - 0x2d, 0x62, 0x5e, 0x8e, 0x79, 0xb6, 0x22, 0xe9, 0x99, 0xa6, 0x41, 0xd8, 0xc4, 0xb3, 0xbf, 0x9a, - 0x83, 0x92, 0xbc, 0x39, 0x1e, 0x40, 0x94, 0xcf, 0x5b, 0x30, 0xa1, 0x4e, 0xbe, 0xd9, 0x91, 0x0a, - 0x1f, 0x8c, 0x6b, 0x27, 0xbf, 0xbb, 0x56, 0xfe, 0x67, 0x7e, 0x2d, 0xd0, 0x66, 0x2d, 0x36, 0x99, - 0xe1, 0x24, 0x6f, 0x74, 0x1b, 0x20, 0xea, 0x44, 0x31, 0x69, 0x1a, 0x87, 0x3b, 0xb6, 0x31, 0xe3, - 0x66, 0xdd, 0x20, 0x24, 0x74, 0x7e, 0xad, 0x05, 0x55, 0xb2, 0xa9, 0x30, 0xb5, 0x1d, 0xa2, 0xcb, - 0xb0, 0x41, 0xc9, 0xfe, 0x47, 0x39, 0x38, 0x9b, 0x16, 0x09, 0x7d, 0x14, 0xc6, 0x25, 0x77, 0x23, - 0x6b, 0xb6, 0xbc, 0x2e, 0x1f, 0xc7, 0x06, 0xec, 0xc1, 0xc1, 0xcc, 0x4c, 0x77, 0x02, 0xf2, 0x59, - 0x13, 0x05, 0x27, 0x88, 0xf1, 0xeb, 0x07, 0x71, 0x4f, 0x56, 0xe9, 0xcc, 0xb7, 0x5a, 0xe2, 0x0e, - 0xc1, 0xb8, 0x7e, 0x30, 0xa1, 0x38, 0x85, 0x8d, 0x36, 0xe0, 0xbc, 0x51, 0xb2, 0x46, 0xbc, 0xfa, - 0xce, 0x76, 0x10, 0xca, 0xed, 0xc9, 0xf3, 0xda, 0x6b, 0xa4, 0x1b, 0x07, 0xf7, 0xac, 0x49, 0x97, - 0x4c, 0xd7, 0x69, 0x39, 0xae, 0x17, 0x77, 0xc4, 0x69, 0x95, 0xd2, 0x4d, 0x0b, 0xa2, 0x1c, 0x2b, - 0x0c, 0x7b, 0x15, 0x46, 0x06, 0x1c, 0x41, 0x03, 0x99, 0xc5, 0x6f, 0x41, 0x89, 0x92, 0x93, 0x36, - 0x52, 0x16, 0x24, 0x03, 0x28, 0xc9, 0xc4, 0x97, 0xc8, 0x86, 0xbc, 0xe7, 0xc8, 0x1b, 0x1e, 0xd5, - 0xac, 0xe5, 0x28, 0x6a, 0xb3, 0x9d, 0x26, 0x05, 0xa2, 0x17, 0x21, 0x4f, 0xf6, 0x5b, 0xe9, 0xab, - 0x9c, 0xab, 0xfb, 0x2d, 0x2f, 0x24, 0x11, 0x45, 0x22, 0xfb, 0x2d, 0x74, 0x11, 0x72, 0x5e, 0x55, - 0x2c, 0x52, 0x20, 0x70, 0x72, 0xcb, 0x8b, 0x38, 0xe7, 0x55, 0xed, 0x7d, 0x28, 0xab, 0x4c, 0x9b, - 0x68, 0x57, 0xea, 0x6e, 0x2b, 0x0b, 0x57, 0x0f, 0x49, 0xb7, 0x8f, 0xd6, 0x6e, 0x03, 0xe8, 0xd0, - 0x90, 0xac, 0xf4, 0xcb, 0x65, 0x18, 0x71, 0x03, 0x11, 0x51, 0x56, 0xd2, 0x64, 0x98, 0xd2, 0x66, - 0x10, 0xfb, 0x0e, 0x4c, 0xde, 0xf4, 0x83, 0xfb, 0x2c, 0xdf, 0xdc, 0x35, 0x8f, 0x34, 0xaa, 0x94, - 0x70, 0x8d, 0xfe, 0x48, 0x9b, 0x08, 0x0c, 0x8a, 0x39, 0x4c, 0xa5, 0xa3, 0xcc, 0xf5, 0x4b, 0x47, - 0x69, 0x7f, 0xca, 0x82, 0xb3, 0x2a, 0x66, 0x41, 0x6a, 0xe3, 0xd7, 0x61, 0x7c, 0xbb, 0xed, 0x35, - 0xaa, 0xe2, 0x7f, 0x7a, 0xaf, 0x5f, 0x31, 0x60, 0x38, 0x81, 0x49, 0x77, 0x26, 0xdb, 0x9e, 0xef, - 0x84, 0x9d, 0x0d, 0xad, 0xfe, 0x95, 0x46, 0xa8, 0x28, 0x08, 0x36, 0xb0, 0xec, 0xcf, 0xe4, 0x60, - 0x22, 0x11, 0xa2, 0x8d, 0x1a, 0x50, 0x22, 0x0d, 0x76, 0x02, 0x25, 0x3f, 0xea, 0x49, 0x13, 0xad, - 0xa8, 0x81, 0x78, 0x55, 0xd0, 0xc5, 0x8a, 0xc3, 0x13, 0x71, 0xd5, 0x61, 0x7f, 0x3b, 0x0f, 0xd3, - 0xfc, 0xe0, 0xad, 0xaa, 0x7c, 0x0a, 0x56, 0xa5, 0x75, 0xf2, 0xd7, 0x75, 0x3a, 0x04, 0xde, 0x1d, - 0xdb, 0x27, 0x4d, 0x15, 0xd6, 0x9b, 0xd1, 0x40, 0xb7, 0xdd, 0x7f, 0x27, 0x75, 0xdb, 0x9d, 0xcb, - 0xc2, 0xa1, 0xbf, 0xaf, 0x44, 0x3f, 0x5c, 0xd7, 0xdf, 0x7f, 0x3f, 0x07, 0x67, 0x52, 0x79, 0xd8, - 0xd0, 0x97, 0x93, 0x79, 0x72, 0xac, 0x2c, 0x8e, 0x67, 0x1e, 0x9a, 0x0d, 0x6c, 0xb8, 0x6c, 0x39, - 0x8f, 0x6b, 0xc0, 0xff, 0x61, 0x0e, 0x26, 0x93, 0x09, 0xe4, 0x9e, 0xc0, 0x9e, 0xfa, 0x00, 0x94, - 0x59, 0x5a, 0x26, 0x96, 0xcf, 0x9c, 0x9f, 0x02, 0xb1, 0x40, 0xec, 0x55, 0x59, 0x88, 0x35, 0xfc, - 0x89, 0x48, 0x42, 0x64, 0xff, 0x03, 0x0b, 0x2e, 0xf0, 0x56, 0xa6, 0xc7, 0xe1, 0xdf, 0xe8, 0xd5, - 0xbb, 0x1f, 0xcb, 0x56, 0xc0, 0x54, 0x1a, 0x8f, 0xa3, 0xfa, 0x97, 0xe5, 0x51, 0x16, 0xd2, 0x26, - 0x87, 0xc2, 0x13, 0x28, 0xec, 0x50, 0x83, 0xc1, 0xfe, 0xc3, 0x3c, 0xe8, 0xd4, 0xd1, 0xc8, 0x13, - 0xe1, 0x06, 0x99, 0xa4, 0x33, 0xd9, 0xec, 0xf8, 0xae, 0x4e, 0x52, 0x5d, 0x4a, 0x45, 0x1b, 0xfc, - 0xba, 0x05, 0x63, 0x9e, 0xef, 0xc5, 0x9e, 0xc3, 0x8c, 0xce, 0x6c, 0x72, 0xfb, 0x2a, 0x76, 0xcb, - 0x9c, 0x72, 0x10, 0x9a, 0x47, 0x87, 0x8a, 0x19, 0x36, 0x39, 0xa3, 0x4f, 0x0a, 0x87, 0xb4, 0x7c, - 0x66, 0xc1, 0x2a, 0xa5, 0x94, 0x17, 0x5a, 0x0b, 0x0a, 0x21, 0x89, 0x43, 0x19, 0x26, 0x74, 0xf3, - 0xa4, 0x5e, 0xc6, 0x71, 0xd8, 0xd9, 0x8c, 0x43, 0x27, 0x26, 0x75, 0x63, 0xd3, 0xce, 0x8a, 0x31, - 0x67, 0x64, 0x47, 0x80, 0xba, 0xfb, 0x62, 0x48, 0x67, 0x9f, 0x39, 0x28, 0x3b, 0xed, 0x38, 0x68, - 0xd2, 0x6e, 0x12, 0xa7, 0x9b, 0xda, 0x9d, 0x49, 0x02, 0xb0, 0xc6, 0xb1, 0xbf, 0x5c, 0x80, 0x94, - 0xff, 0x3f, 0xda, 0x37, 0xd3, 0x9e, 0x5b, 0xd9, 0xa6, 0x3d, 0x57, 0xc2, 0xf4, 0x4a, 0x7d, 0x8e, - 0xea, 0x50, 0x68, 0xed, 0x38, 0x91, 0xb4, 0x29, 0xdf, 0x92, 0xdd, 0xb4, 0x41, 0x0b, 0x1f, 0x1c, - 0xcc, 0xfc, 0xcc, 0x60, 0x67, 0x14, 0x74, 0xac, 0xce, 0xf1, 0x78, 0x57, 0xcd, 0x9a, 0xd1, 0xc0, - 0x9c, 0xbe, 0x79, 0x4a, 0x91, 0x3f, 0xe2, 0x3e, 0xec, 0xd3, 0x22, 0xf3, 0x1a, 0x26, 0x51, 0xbb, - 0x11, 0x8b, 0xd1, 0xf0, 0x56, 0x86, 0xb3, 0x8c, 0x13, 0xd6, 0xd1, 0x63, 0xfc, 0x3f, 0x36, 0x98, - 0xa2, 0x8f, 0x42, 0x39, 0x8a, 0x9d, 0x30, 0x3e, 0x66, 0xac, 0x89, 0xea, 0xf4, 0x4d, 0x49, 0x04, - 0x6b, 0x7a, 0xe8, 0x6d, 0x96, 0xdd, 0xc9, 0x8b, 0x76, 0x8e, 0xe9, 0x47, 0x2a, 0x33, 0x41, 0x09, - 0x0a, 0xd8, 0xa0, 0x46, 0x4d, 0x76, 0x36, 0xb6, 0xb9, 0xf3, 0x44, 0x89, 0xed, 0xc9, 0x94, 0x2a, - 0xc4, 0x0a, 0x82, 0x0d, 0x2c, 0xfb, 0x97, 0xe0, 0x5c, 0xfa, 0x9d, 0x14, 0x71, 0x6c, 0x59, 0x0f, - 0x83, 0x76, 0x2b, 0xbd, 0x27, 0x61, 0xef, 0x68, 0x60, 0x0e, 0xa3, 0x7b, 0x92, 0x5d, 0xcf, 0xaf, - 0xa6, 0xf7, 0x24, 0x37, 0x3d, 0xbf, 0x8a, 0x19, 0x64, 0x80, 0x7c, 0xf0, 0xff, 0xc2, 0x82, 0xcb, - 0x47, 0x3d, 0xe7, 0x82, 0x9e, 0x87, 0x91, 0xfb, 0x4e, 0x28, 0xb3, 0xc5, 0x31, 0xdd, 0x71, 0xc7, - 0x09, 0x7d, 0xcc, 0x4a, 0x51, 0x07, 0x8a, 0x3c, 0xbe, 0x4e, 0x18, 0xb0, 0x6f, 0x65, 0xfb, 0xb8, - 0xcc, 0x4d, 0x62, 0x58, 0xd0, 0x3c, 0xb6, 0x0f, 0x0b, 0x86, 0xf6, 0xbb, 0x16, 0xa0, 0xf5, 0x3d, - 0x12, 0x86, 0x5e, 0xd5, 0x88, 0x08, 0x44, 0xaf, 0xc1, 0xf8, 0xdd, 0xcd, 0xf5, 0xb5, 0x8d, 0xc0, - 0xf3, 0x59, 0x8c, 0xb0, 0x11, 0x1b, 0x72, 0xc3, 0x28, 0xc7, 0x09, 0x2c, 0xb4, 0x00, 0x53, 0x77, - 0xef, 0xd1, 0x7d, 0xd4, 0xd5, 0xfd, 0x56, 0x48, 0xa2, 0x48, 0xd9, 0xe4, 0xe2, 0xe4, 0xec, 0xc6, - 0x5b, 0x29, 0x20, 0xee, 0xc6, 0x47, 0xeb, 0x70, 0xa1, 0xc9, 0x2d, 0x70, 0xb6, 0x7d, 0x8c, 0xb8, - 0x39, 0x1e, 0xca, 0xc4, 0x01, 0xcf, 0x1e, 0x1e, 0xcc, 0x5c, 0x58, 0xed, 0x85, 0x80, 0x7b, 0xd7, - 0xb3, 0xbf, 0x95, 0x83, 0x31, 0xe3, 0x49, 0xa4, 0x01, 0x36, 0xca, 0xa9, 0x57, 0x9c, 0x72, 0x03, - 0xbe, 0xe2, 0xf4, 0x12, 0x94, 0x5a, 0x41, 0xc3, 0x73, 0x3d, 0x95, 0xe5, 0x80, 0x65, 0xdb, 0xda, - 0x10, 0x65, 0x58, 0x41, 0xd1, 0x7d, 0x28, 0xab, 0x67, 0x42, 0x44, 0x50, 0x5c, 0x56, 0x47, 0x05, - 0x6a, 0xf2, 0xea, 0xe7, 0x3f, 0x34, 0x2f, 0x64, 0x43, 0x91, 0x8d, 0x7c, 0xe9, 0x56, 0xc4, 0x22, - 0x1f, 0xd8, 0x94, 0x88, 0xb0, 0x80, 0xd8, 0xbf, 0x3a, 0x0a, 0xe7, 0x7b, 0x65, 0x88, 0x42, 0xbf, - 0x00, 0x45, 0x2e, 0x63, 0x36, 0x49, 0x08, 0x7b, 0xf1, 0x58, 0x62, 0x04, 0x85, 0x58, 0xec, 0x37, - 0x16, 0x3c, 0x05, 0xf7, 0x86, 0xb3, 0x2d, 0xcc, 0x88, 0xd3, 0xe1, 0xbe, 0xe2, 0x68, 0xee, 0x2b, - 0x0e, 0xe7, 0xde, 0x70, 0xb6, 0xd1, 0x3e, 0x14, 0xea, 0x5e, 0x4c, 0x1c, 0x61, 0x4c, 0xdf, 0x39, - 0x15, 0xe6, 0xc4, 0xe1, 0xde, 0xeb, 0xec, 0x27, 0xe6, 0x0c, 0xd1, 0x37, 0x2c, 0x38, 0xb3, 0x9d, - 0x0c, 0x24, 0x11, 0xab, 0x8a, 0x73, 0x0a, 0x59, 0xc0, 0x92, 0x8c, 0x2a, 0xe7, 0x0e, 0x0f, 0x66, - 0xce, 0xa4, 0x0a, 0x71, 0x5a, 0x1c, 0xf4, 0x2b, 0x16, 0x8c, 0xd6, 0xbc, 0x86, 0x91, 0x01, 0xe7, - 0x14, 0x3e, 0xce, 0x35, 0xc6, 0x40, 0xaf, 0xbc, 0xfc, 0x7f, 0x84, 0x25, 0xe7, 0x7e, 0xd7, 0x79, - 0xc5, 0x93, 0x5e, 0xe7, 0x8d, 0x3e, 0xa6, 0xed, 0xd3, 0xdf, 0xca, 0xc1, 0x8b, 0x03, 0x7c, 0x23, - 0x33, 0x30, 0xc1, 0x3a, 0x22, 0x30, 0xe1, 0x32, 0x8c, 0x84, 0xa4, 0x15, 0xa4, 0xd7, 0x3b, 0xe6, - 0x39, 0xc4, 0x20, 0xe8, 0x05, 0xc8, 0x3b, 0x2d, 0x4f, 0x2c, 0x77, 0xea, 0xb6, 0x7f, 0x7e, 0x63, - 0x19, 0xd3, 0x72, 0xfa, 0xa5, 0xcb, 0xdb, 0x32, 0xbc, 0x29, 0x9b, 0xb4, 0xb2, 0xfd, 0xa2, 0xa5, - 0xf8, 0x86, 0x46, 0x41, 0xb1, 0xe6, 0x6b, 0xaf, 0xc3, 0xc5, 0xfe, 0x23, 0x04, 0xbd, 0x0a, 0x63, - 0xdb, 0xa1, 0xe3, 0xbb, 0x3b, 0xab, 0x4e, 0xec, 0xca, 0x3b, 0x77, 0xe6, 0x3f, 0x59, 0xd1, 0xc5, - 0xd8, 0xc4, 0xb1, 0xbf, 0x9d, 0xeb, 0x4d, 0x91, 0x2b, 0x81, 0x61, 0x7a, 0x58, 0xf4, 0x5f, 0xae, - 0x4f, 0xff, 0xdd, 0x83, 0x52, 0xcc, 0xbc, 0xe1, 0x49, 0x4d, 0x68, 0x92, 0xcc, 0x02, 0xba, 0xd8, - 0x5a, 0xb3, 0x25, 0x88, 0x63, 0xc5, 0x86, 0xaa, 0xfc, 0x86, 0x4e, 0x9e, 0x23, 0x54, 0x7e, 0xea, - 0x1c, 0x6d, 0x11, 0xce, 0x1a, 0xc9, 0xfe, 0xb8, 0x33, 0x30, 0xbf, 0x46, 0x55, 0x11, 0x32, 0x1b, - 0x29, 0x38, 0xee, 0xaa, 0x61, 0x7f, 0x33, 0x07, 0xcf, 0xf6, 0xd5, 0x6c, 0xfa, 0xae, 0xd7, 0x7a, - 0xc8, 0x5d, 0xef, 0x89, 0x07, 0xa8, 0xd9, 0xc1, 0x23, 0x8f, 0xa6, 0x83, 0x5f, 0x86, 0x92, 0xe7, - 0x47, 0xc4, 0x6d, 0x87, 0xbc, 0xd3, 0x0c, 0xb7, 0xbc, 0x65, 0x51, 0x8e, 0x15, 0x86, 0xfd, 0x47, - 0xfd, 0x87, 0x1a, 0x5d, 0xe5, 0x7e, 0x64, 0x7b, 0xe9, 0x0d, 0x98, 0x70, 0x5a, 0x2d, 0x8e, 0xc7, - 0xee, 0xd5, 0x52, 0x31, 0x6f, 0xf3, 0x26, 0x10, 0x27, 0x71, 0x8d, 0x31, 0x5c, 0xec, 0x37, 0x86, - 0xed, 0xef, 0x17, 0xa1, 0x4c, 0x7b, 0x60, 0x21, 0x24, 0xd5, 0x88, 0x76, 0x40, 0x3b, 0x6c, 0x88, - 0x5e, 0x54, 0x1d, 0x70, 0x0b, 0xaf, 0x60, 0x5a, 0x9e, 0xd8, 0x25, 0xe7, 0x86, 0x0a, 0x89, 0xc9, - 0x1f, 0x19, 0x12, 0xf3, 0x06, 0x4c, 0x44, 0xd1, 0xce, 0x46, 0xe8, 0xed, 0x39, 0x31, 0xb5, 0xbd, - 0x85, 0xdf, 0x82, 0x76, 0x63, 0xdf, 0xbc, 0xae, 0x81, 0x38, 0x89, 0x8b, 0x96, 0x60, 0x4a, 0x07, - 0xa6, 0x90, 0x30, 0x66, 0x6e, 0x0a, 0xbc, 0xab, 0x94, 0x17, 0xb9, 0x0e, 0x65, 0x11, 0x08, 0xb8, - 0xbb, 0x0e, 0x9d, 0xd2, 0x89, 0x42, 0x2a, 0x48, 0x31, 0x39, 0xa5, 0x13, 0x74, 0xa8, 0x2c, 0x5d, - 0x35, 0xd0, 0x2a, 0x9c, 0xe3, 0xe3, 0x82, 0xbd, 0x8a, 0xa7, 0x5a, 0xc4, 0xdd, 0x4a, 0x9e, 0x13, - 0x84, 0xce, 0x2d, 0x75, 0xa3, 0xe0, 0x5e, 0xf5, 0xa8, 0x61, 0xad, 0x8a, 0x97, 0x17, 0xc5, 0x06, - 0x4f, 0x19, 0xd6, 0x8a, 0xcc, 0x72, 0x15, 0x9b, 0x78, 0xe8, 0x23, 0xf0, 0x8c, 0xfe, 0xcb, 0x1d, - 0xc2, 0xf8, 0xa9, 0xc7, 0xa2, 0x88, 0xf9, 0x53, 0x89, 0xe6, 0x96, 0x7a, 0xa2, 0x55, 0x71, 0xbf, - 0xfa, 0x68, 0x1b, 0x2e, 0x2a, 0xd0, 0x55, 0xba, 0x8b, 0x69, 0x85, 0x5e, 0x44, 0x2a, 0x4e, 0x44, - 0x6e, 0x85, 0x0d, 0x16, 0x25, 0x58, 0xd6, 0x29, 0xb1, 0x97, 0xbc, 0xf8, 0x7a, 0x2f, 0x4c, 0xbc, - 0x82, 0x1f, 0x42, 0x05, 0xcd, 0x41, 0x99, 0xf8, 0xce, 0x76, 0x83, 0xac, 0x2f, 0x2c, 0xb3, 0xd8, - 0x41, 0xe3, 0x90, 0xe5, 0xaa, 0x04, 0x60, 0x8d, 0xa3, 0xae, 0xca, 0xc6, 0xfb, 0xbe, 0xdc, 0xb6, - 0x01, 0xe7, 0xeb, 0x6e, 0x8b, 0x2e, 0x94, 0x9e, 0x4b, 0xe6, 0x5d, 0x97, 0xee, 0x84, 0xe9, 0x87, - 0x99, 0x60, 0x35, 0xd4, 0x3d, 0xf0, 0xd2, 0xc2, 0x46, 0x17, 0x0e, 0xee, 0x59, 0x93, 0x2a, 0x9e, - 0x56, 0x18, 0xec, 0x77, 0xa6, 0xcf, 0x25, 0x15, 0xcf, 0x06, 0x2d, 0xc4, 0x1c, 0x66, 0xff, 0x89, - 0x05, 0x13, 0x6a, 0x8e, 0x3d, 0x02, 0x57, 0x98, 0x46, 0xd2, 0x15, 0x66, 0xe9, 0xa4, 0x87, 0x6a, - 0x42, 0xf2, 0x3e, 0xf7, 0xa9, 0xbf, 0x07, 0x00, 0xec, 0x5d, 0x61, 0x8f, 0x65, 0x0f, 0x91, 0x5a, - 0xd6, 0xea, 0xab, 0x65, 0x9f, 0x58, 0x2d, 0xd2, 0x2b, 0xb8, 0xa7, 0xf0, 0x78, 0x83, 0x7b, 0x36, - 0xe1, 0x82, 0x5c, 0x03, 0xf9, 0x39, 0xc3, 0xf5, 0x20, 0x52, 0x4a, 0xa9, 0x54, 0x79, 0x41, 0x10, - 0xba, 0xb0, 0xdc, 0x0b, 0x09, 0xf7, 0xae, 0x9b, 0x58, 0x7a, 0x47, 0x8f, 0x5a, 0x7a, 0xf5, 0x3c, - 0x5c, 0xa9, 0xc9, 0x54, 0x73, 0xa9, 0x79, 0xb8, 0x72, 0x6d, 0x13, 0x6b, 0x9c, 0xde, 0xca, 0xb8, - 0x9c, 0x91, 0x32, 0x86, 0xa1, 0x95, 0xb1, 0x54, 0x0b, 0x63, 0x7d, 0xd5, 0x82, 0x3c, 0xda, 0x18, - 0xef, 0x7b, 0xb4, 0xf1, 0x26, 0x4c, 0x7a, 0xfe, 0x0e, 0x09, 0xbd, 0x98, 0x54, 0xd9, 0x5c, 0x10, - 0xaf, 0xb5, 0x2a, 0x07, 0x94, 0xe5, 0x04, 0x14, 0xa7, 0xb0, 0x93, 0xba, 0x6c, 0x72, 0x00, 0x5d, - 0xd6, 0x67, 0x05, 0x39, 0x93, 0xcd, 0x0a, 0x72, 0xf6, 0xe4, 0x2b, 0xc8, 0xd4, 0xa9, 0xae, 0x20, - 0x28, 0x93, 0x15, 0x64, 0x10, 0xe5, 0x6c, 0xee, 0x52, 0xce, 0x1f, 0xb1, 0x4b, 0xe9, 0xb7, 0x7c, - 0x5c, 0x38, 0xee, 0xf2, 0x61, 0x7f, 0x2e, 0x07, 0x17, 0xb4, 0xee, 0xa4, 0x23, 0xd6, 0xab, 0x51, - 0xed, 0xc1, 0x32, 0x8c, 0x72, 0xbf, 0x08, 0xc3, 0x9b, 0x4a, 0x3b, 0x66, 0x29, 0x08, 0x36, 0xb0, - 0x98, 0x53, 0x12, 0x09, 0x59, 0xbe, 0x91, 0xb4, 0x62, 0x5d, 0x10, 0xe5, 0x58, 0x61, 0xd0, 0x31, - 0x41, 0x7f, 0x0b, 0x47, 0xcf, 0x74, 0x0c, 0xf2, 0x82, 0x06, 0x61, 0x13, 0x0f, 0xbd, 0xc4, 0x99, - 0xb0, 0x49, 0x4d, 0x95, 0xeb, 0xb8, 0x48, 0x8e, 0x2f, 0xe7, 0xb1, 0x82, 0x4a, 0x71, 0x98, 0xf7, - 0x59, 0xa1, 0x5b, 0x1c, 0x76, 0x0b, 0xa4, 0x30, 0xec, 0xff, 0x6b, 0xc1, 0xb3, 0x3d, 0xbb, 0xe2, - 0x11, 0x2c, 0x98, 0xfb, 0xc9, 0x05, 0x73, 0xf3, 0xe4, 0x0b, 0x66, 0x57, 0x2b, 0xfa, 0x2c, 0x9e, - 0xff, 0xc1, 0x82, 0x49, 0x8d, 0xff, 0x08, 0x9a, 0xea, 0x25, 0x9b, 0x7a, 0x3d, 0xab, 0xa6, 0xf2, - 0x23, 0xb8, 0x44, 0xdb, 0xfe, 0x84, 0xb5, 0x8d, 0x1f, 0xa6, 0xcf, 0xbb, 0xf2, 0x71, 0xdd, 0x23, - 0x0e, 0x91, 0x3b, 0x50, 0x64, 0xe9, 0x2d, 0xa3, 0x6c, 0x0e, 0xf5, 0x93, 0xfc, 0x99, 0x5b, 0xa9, - 0x3e, 0xd4, 0x67, 0x7f, 0x23, 0x2c, 0x18, 0xb2, 0x6c, 0x38, 0x5e, 0x44, 0x35, 0x70, 0x55, 0xf8, - 0x71, 0xe9, 0x6c, 0x38, 0xa2, 0x1c, 0x2b, 0x0c, 0xbb, 0x09, 0xd3, 0x49, 0xe2, 0x8b, 0xa4, 0xc6, - 0xee, 0x4e, 0x07, 0x6a, 0xe6, 0x1c, 0x94, 0x1d, 0x56, 0x6b, 0xa5, 0xed, 0xa4, 0xdf, 0x53, 0x99, - 0x97, 0x00, 0xac, 0x71, 0xec, 0xdf, 0xb1, 0xe0, 0x5c, 0x8f, 0xc6, 0x64, 0xe8, 0xbf, 0x16, 0x6b, - 0x2d, 0xd0, 0xe7, 0xd5, 0xe3, 0x2a, 0xa9, 0x39, 0xf2, 0x76, 0xce, 0xd0, 0x93, 0x8b, 0xbc, 0x18, - 0x4b, 0xb8, 0xfd, 0xbf, 0x2c, 0x38, 0x93, 0x94, 0x35, 0x42, 0x37, 0x00, 0xf1, 0xc6, 0x2c, 0x7a, - 0x91, 0x1b, 0xec, 0x91, 0xb0, 0x43, 0x5b, 0xce, 0xa5, 0xbe, 0x28, 0x28, 0xa1, 0xf9, 0x2e, 0x0c, - 0xdc, 0xa3, 0x16, 0xcb, 0xd6, 0x51, 0x55, 0xbd, 0x2d, 0x47, 0xca, 0xed, 0x2c, 0x47, 0x8a, 0xfe, - 0x98, 0xe6, 0x0d, 0x86, 0x62, 0x89, 0x4d, 0xfe, 0xf6, 0xbb, 0x23, 0xa0, 0x1c, 0x5c, 0xd9, 0x3d, - 0x50, 0x46, 0xb7, 0x68, 0x89, 0x47, 0x77, 0xf2, 0x43, 0x3c, 0xc3, 0x3c, 0xf2, 0xb0, 0x3b, 0x1a, - 0xfe, 0xfe, 0x83, 0x79, 0x5a, 0xa5, 0x5a, 0xb8, 0xa5, 0x41, 0xd8, 0xc4, 0xa3, 0x92, 0x34, 0xbc, - 0x3d, 0xc2, 0x2b, 0x15, 0x93, 0x92, 0xac, 0x48, 0x00, 0xd6, 0x38, 0x54, 0x92, 0xaa, 0x57, 0xab, - 0x89, 0x2d, 0xaf, 0x92, 0x84, 0xf6, 0x0e, 0x66, 0x10, 0x8a, 0xb1, 0x13, 0x04, 0xbb, 0xc2, 0xa2, - 0x54, 0x18, 0xd7, 0x83, 0x60, 0x17, 0x33, 0x08, 0xb5, 0x81, 0xfc, 0x20, 0x6c, 0xb2, 0xf7, 0x6e, - 0xaa, 0x8a, 0x8b, 0xb0, 0x24, 0x95, 0x0d, 0xb4, 0xd6, 0x8d, 0x82, 0x7b, 0xd5, 0xa3, 0x23, 0xb0, - 0x15, 0x92, 0xaa, 0xe7, 0xc6, 0x26, 0x35, 0x48, 0x8e, 0xc0, 0x8d, 0x2e, 0x0c, 0xdc, 0xa3, 0x16, - 0x9a, 0x87, 0x33, 0xd2, 0x41, 0x59, 0xc6, 0x70, 0x8d, 0x25, 0x63, 0x46, 0x70, 0x12, 0x8c, 0xd3, - 0xf8, 0x54, 0xdb, 0x34, 0x45, 0xf8, 0x26, 0x33, 0x3c, 0x0d, 0x6d, 0x23, 0xc3, 0x3a, 0xb1, 0xc2, - 0xb0, 0x3f, 0x9d, 0xa7, 0xab, 0x63, 0x9f, 0x14, 0xa4, 0x8f, 0xec, 0xd6, 0x36, 0x39, 0x22, 0x47, - 0x06, 0x18, 0x91, 0xaf, 0xc1, 0xf8, 0xdd, 0x28, 0xf0, 0xd5, 0x8d, 0x68, 0xa1, 0xef, 0x8d, 0xa8, - 0x81, 0xd5, 0xfb, 0x46, 0xb4, 0x98, 0xd5, 0x8d, 0xe8, 0xe8, 0x31, 0x6f, 0x44, 0xff, 0xa0, 0x00, - 0x2a, 0x81, 0xe0, 0x1a, 0x89, 0xef, 0x07, 0xe1, 0xae, 0xe7, 0xd7, 0x99, 0x63, 0xf7, 0x37, 0x2c, - 0x18, 0xe7, 0xf3, 0x65, 0xc5, 0x74, 0xf2, 0xac, 0x65, 0x94, 0x34, 0x2f, 0xc1, 0x6c, 0x76, 0xcb, - 0x60, 0x94, 0xca, 0xb6, 0x6e, 0x82, 0x70, 0x42, 0x22, 0xf4, 0x8b, 0x00, 0xf2, 0xe5, 0x97, 0x5a, - 0x46, 0x6f, 0xa2, 0xab, 0x77, 0x78, 0x48, 0x4d, 0xdb, 0xa6, 0x5b, 0x8a, 0x09, 0x36, 0x18, 0xa2, - 0xcf, 0xa5, 0xdf, 0x03, 0xfb, 0xe4, 0xa9, 0xf4, 0xcd, 0x20, 0xee, 0xaf, 0x18, 0x46, 0x3d, 0xbf, - 0x4e, 0xc7, 0x89, 0xb8, 0x44, 0x7e, 0x7f, 0xaf, 0xa0, 0x88, 0x95, 0xc0, 0xa9, 0x56, 0x9c, 0x86, - 0xe3, 0xbb, 0x24, 0x5c, 0xe6, 0xe8, 0xe6, 0xf3, 0x1f, 0xac, 0x00, 0x4b, 0x42, 0x5d, 0x59, 0x21, - 0x0b, 0x83, 0x64, 0x85, 0xbc, 0xf8, 0x61, 0x98, 0xea, 0xfa, 0x98, 0x43, 0x79, 0xbb, 0x1e, 0xdf, - 0x51, 0xd6, 0xfe, 0x97, 0x45, 0xbd, 0x68, 0xad, 0x05, 0x55, 0x9e, 0x9b, 0x30, 0xd4, 0x5f, 0x54, - 0xd8, 0x9e, 0x19, 0x0e, 0x11, 0xe3, 0x09, 0x11, 0x55, 0x88, 0x4d, 0x96, 0x74, 0x8c, 0xb6, 0x9c, - 0x90, 0xf8, 0xa7, 0x3d, 0x46, 0x37, 0x14, 0x13, 0x6c, 0x30, 0x44, 0x3b, 0x09, 0x77, 0xb7, 0x6b, - 0x27, 0x77, 0x77, 0x63, 0x31, 0x97, 0xbd, 0x92, 0xaf, 0x7d, 0xc5, 0x82, 0x49, 0x3f, 0x31, 0x72, - 0xc5, 0x85, 0xc2, 0xd6, 0x69, 0xcc, 0x0a, 0x9e, 0x7f, 0x36, 0x59, 0x86, 0x53, 0xfc, 0x7b, 0x2d, - 0x69, 0x85, 0x21, 0x97, 0x34, 0x9d, 0xe4, 0xb4, 0xd8, 0x2f, 0xc9, 0x29, 0xf2, 0x55, 0x2a, 0xe5, - 0xd1, 0xcc, 0x53, 0x29, 0x43, 0x8f, 0x34, 0xca, 0x77, 0xa0, 0xec, 0x86, 0xc4, 0x89, 0x8f, 0x99, - 0x55, 0x97, 0xdd, 0xa6, 0x2e, 0x48, 0x02, 0x58, 0xd3, 0xb2, 0xff, 0x7d, 0x1e, 0xce, 0xca, 0x1e, - 0x91, 0xae, 0x40, 0x74, 0x7d, 0xe4, 0x7c, 0xb5, 0x71, 0xab, 0xd6, 0xc7, 0xeb, 0x12, 0x80, 0x35, - 0x0e, 0xb5, 0xc7, 0xda, 0x11, 0x59, 0x6f, 0x11, 0x7f, 0xc5, 0xdb, 0x8e, 0xc4, 0x45, 0x98, 0x9a, - 0x28, 0xb7, 0x34, 0x08, 0x9b, 0x78, 0xd4, 0x18, 0xe7, 0x76, 0x71, 0x94, 0xf6, 0xac, 0x13, 0xf6, - 0x36, 0x96, 0x70, 0xf4, 0x1b, 0x3d, 0x73, 0xa2, 0x67, 0xe3, 0x53, 0xda, 0xe5, 0x01, 0x35, 0x64, - 0x32, 0xf4, 0x2f, 0x5b, 0x70, 0x66, 0x37, 0x11, 0x14, 0x23, 0x55, 0xf2, 0x09, 0xc3, 0x37, 0x93, - 0x91, 0x36, 0x7a, 0x08, 0x27, 0xcb, 0x23, 0x9c, 0xe6, 0x6e, 0xff, 0x1f, 0x0b, 0x4c, 0xf5, 0x34, - 0x98, 0x65, 0x65, 0x3c, 0x64, 0x92, 0x3b, 0xe2, 0x21, 0x13, 0x69, 0x84, 0xe5, 0x07, 0x33, 0xfa, - 0x47, 0x86, 0x30, 0xfa, 0x0b, 0x7d, 0xad, 0xb6, 0x17, 0x20, 0xdf, 0xf6, 0xaa, 0xc2, 0x6e, 0xd7, - 0xb7, 0x7a, 0xcb, 0x8b, 0x98, 0x96, 0xdb, 0xbf, 0x57, 0xd0, 0xfb, 0x74, 0xe1, 0x0a, 0xf9, 0x23, - 0xd1, 0xec, 0x9a, 0x8a, 0xc6, 0xe5, 0x2d, 0x5f, 0xeb, 0x8a, 0xc6, 0xfd, 0xa9, 0xe1, 0x3d, 0x5d, - 0x79, 0x07, 0xf5, 0x0b, 0xc6, 0x1d, 0x3d, 0xc2, 0xcd, 0xf5, 0x2e, 0x94, 0xe8, 0xd6, 0x86, 0x1d, - 0xb8, 0x95, 0x12, 0x42, 0x95, 0xae, 0x8b, 0xf2, 0x07, 0x07, 0x33, 0x3f, 0x39, 0xbc, 0x58, 0xb2, - 0x36, 0x56, 0xf4, 0x51, 0x04, 0x65, 0xfa, 0x9b, 0x79, 0xe4, 0x8a, 0x4d, 0xd3, 0x2d, 0xa5, 0x8b, - 0x24, 0x20, 0x13, 0x77, 0x5f, 0xcd, 0x07, 0xf9, 0x50, 0x66, 0xef, 0x31, 0x30, 0xa6, 0x7c, 0x6f, - 0xb5, 0xa1, 0xfc, 0x62, 0x25, 0xe0, 0xc1, 0xc1, 0xcc, 0x1b, 0xc3, 0x33, 0x55, 0xd5, 0xb1, 0x66, - 0x61, 0x7f, 0x75, 0x44, 0x8f, 0x5d, 0x11, 0x84, 0xfd, 0x23, 0x31, 0x76, 0x5f, 0x4f, 0x8d, 0xdd, - 0xcb, 0x5d, 0x63, 0x77, 0x52, 0xbf, 0x59, 0x90, 0x18, 0x8d, 0x8f, 0x7a, 0x81, 0x3d, 0x7a, 0x1f, - 0xcf, 0x2c, 0x8b, 0x7b, 0x6d, 0x2f, 0x24, 0xd1, 0x46, 0xd8, 0xf6, 0x3d, 0xbf, 0x2e, 0x1e, 0x27, - 0x33, 0x2c, 0x8b, 0x04, 0x18, 0xa7, 0xf1, 0xd9, 0xc3, 0x66, 0x1d, 0xdf, 0xbd, 0xe3, 0xec, 0xf1, - 0x51, 0x65, 0xc4, 0xa5, 0x6e, 0x8a, 0x72, 0xac, 0x30, 0xec, 0x6f, 0xb1, 0xfb, 0x56, 0x23, 0x14, - 0x80, 0x8e, 0x89, 0x06, 0x7b, 0x00, 0x83, 0x07, 0xb5, 0xaa, 0x31, 0xc1, 0x5f, 0xbd, 0xe0, 0x30, - 0x74, 0x1f, 0x46, 0xb7, 0x79, 0x62, 0xec, 0x6c, 0xb2, 0x60, 0x89, 0x2c, 0xdb, 0x2c, 0x59, 0xa4, - 0x4c, 0xb9, 0xfd, 0x40, 0xff, 0xc4, 0x92, 0x9b, 0xfd, 0x77, 0xf3, 0x70, 0x26, 0xf5, 0x3c, 0x43, - 0x22, 0x27, 0x47, 0xee, 0xc8, 0x9c, 0x1c, 0x1f, 0x07, 0xa8, 0x92, 0x56, 0x23, 0xe8, 0x30, 0x33, - 0x67, 0x64, 0x68, 0x33, 0x47, 0x59, 0xc6, 0x8b, 0x8a, 0x0a, 0x36, 0x28, 0x8a, 0x48, 0x5e, 0x9e, - 0xe2, 0x23, 0x15, 0xc9, 0x6b, 0x24, 0x83, 0x2b, 0x3e, 0xda, 0x64, 0x70, 0x1e, 0x9c, 0xe1, 0x22, - 0x2a, 0x87, 0xfb, 0x63, 0xf8, 0xd5, 0x33, 0x57, 0xcd, 0xc5, 0x24, 0x19, 0x9c, 0xa6, 0x6b, 0x7f, - 0x29, 0x47, 0x8d, 0x3d, 0xde, 0xd9, 0x2a, 0xa6, 0xf3, 0x7d, 0x50, 0x74, 0xda, 0xf1, 0x4e, 0xd0, - 0x95, 0xe1, 0x7b, 0x9e, 0x95, 0x62, 0x01, 0x45, 0x2b, 0x30, 0x52, 0xd5, 0x71, 0x7a, 0xc3, 0x08, - 0xa7, 0xcf, 0xcd, 0x9c, 0x98, 0x60, 0x46, 0x05, 0x3d, 0x0f, 0x23, 0xb1, 0x53, 0x4f, 0xbc, 0x5b, - 0xb7, 0xe5, 0xd4, 0x23, 0xcc, 0x4a, 0xcd, 0xb5, 0x68, 0xe4, 0x88, 0xb5, 0xe8, 0x0d, 0x98, 0x88, - 0xbc, 0xba, 0xef, 0xc4, 0xed, 0x90, 0x18, 0x77, 0x34, 0xfa, 0xaa, 0xdc, 0x04, 0xe2, 0x24, 0xae, - 0xfd, 0x6e, 0x19, 0xce, 0xf7, 0x7a, 0x40, 0x38, 0x6b, 0x6f, 0xe7, 0x5e, 0x3c, 0x1e, 0x9d, 0xb7, - 0x73, 0x1f, 0xee, 0x0d, 0xc3, 0xdb, 0xb9, 0x61, 0x78, 0x3b, 0x7f, 0xce, 0x82, 0xb2, 0x72, 0xf2, - 0x15, 0x8e, 0x8a, 0x1f, 0x3d, 0x85, 0x47, 0x9a, 0x25, 0x0b, 0xe1, 0xeb, 0x29, 0xff, 0x62, 0xcd, - 0xfc, 0xf4, 0xdc, 0x9f, 0x1f, 0x2a, 0xd0, 0x50, 0xee, 0xcf, 0xca, 0x37, 0xbc, 0x90, 0x85, 0x6f, - 0x78, 0x9f, 0x4f, 0xd5, 0xd3, 0x37, 0xfc, 0x2b, 0x16, 0x8c, 0x39, 0xef, 0xb4, 0x43, 0xb2, 0x48, - 0xf6, 0xd6, 0x5b, 0x91, 0xd0, 0x5b, 0x1f, 0xcb, 0x5e, 0x80, 0x79, 0xcd, 0x44, 0xa4, 0x22, 0xd5, - 0x05, 0xd8, 0x14, 0x21, 0xe1, 0x0b, 0x3e, 0x9a, 0x85, 0x2f, 0x78, 0x2f, 0x71, 0x8e, 0xf4, 0x05, - 0x7f, 0x03, 0x26, 0xdc, 0x46, 0xe0, 0x93, 0x8d, 0x30, 0x88, 0x03, 0x37, 0x68, 0x08, 0x1b, 0x55, - 0xa9, 0x84, 0x05, 0x13, 0x88, 0x93, 0xb8, 0xfd, 0x1c, 0xc9, 0xcb, 0x27, 0x75, 0x24, 0x87, 0xc7, - 0xe4, 0x48, 0xfe, 0x67, 0x39, 0x98, 0x39, 0xe2, 0xa3, 0xa2, 0xd7, 0x61, 0x3c, 0x08, 0xeb, 0x8e, - 0xef, 0xbd, 0xc3, 0xe3, 0xf8, 0x0a, 0xc9, 0x34, 0x0b, 0xeb, 0x06, 0x0c, 0x27, 0x30, 0xa5, 0xab, - 0x69, 0xb1, 0x8f, 0xab, 0xe9, 0x07, 0x61, 0x2c, 0x26, 0x4e, 0x53, 0xb8, 0x20, 0x88, 0x7d, 0x85, - 0xbe, 0xa7, 0xd1, 0x20, 0x6c, 0xe2, 0xd1, 0x61, 0x34, 0xe9, 0xb8, 0x2e, 0x89, 0x22, 0xe9, 0x4b, - 0x2a, 0xce, 0x3c, 0x32, 0x73, 0x54, 0x65, 0x47, 0x49, 0xf3, 0x09, 0x16, 0x38, 0xc5, 0x92, 0x0a, - 0xef, 0x34, 0x1a, 0xdc, 0x6d, 0x9c, 0xc8, 0x97, 0x68, 0x75, 0xd4, 0xbf, 0x06, 0x61, 0x13, 0xcf, - 0xfe, 0xcd, 0x1c, 0xbc, 0xf0, 0x50, 0xf5, 0x32, 0xb0, 0x9b, 0x6f, 0x3b, 0x22, 0x61, 0xfa, 0x9e, - 0xe3, 0x56, 0x44, 0x42, 0xcc, 0x20, 0xbc, 0x97, 0x5a, 0x2d, 0xe3, 0x19, 0x8f, 0xac, 0xbd, 0xca, - 0x79, 0x2f, 0x25, 0x58, 0xe0, 0x14, 0xcb, 0x74, 0x2f, 0x8d, 0x0c, 0xd8, 0x4b, 0xff, 0x30, 0x07, - 0x2f, 0x0e, 0xa0, 0x84, 0x33, 0xf4, 0xbe, 0x4f, 0x46, 0x2f, 0xe4, 0x1f, 0x4f, 0xf4, 0xc2, 0x71, - 0xbb, 0xeb, 0x5b, 0x39, 0xb8, 0xd8, 0x5f, 0x17, 0xa2, 0x9f, 0xa6, 0x7b, 0x13, 0xe9, 0xc3, 0x60, - 0x46, 0x3e, 0x9c, 0xe3, 0xfb, 0x92, 0x04, 0x08, 0xa7, 0x71, 0xd1, 0x2c, 0x40, 0xcb, 0x89, 0x77, - 0xa2, 0xab, 0xfb, 0x5e, 0x14, 0x8b, 0x98, 0xbd, 0x49, 0x7e, 0xc2, 0x2c, 0x4b, 0xb1, 0x81, 0x41, - 0xd9, 0xb1, 0x7f, 0x8b, 0xc1, 0x5a, 0x10, 0xf3, 0x4a, 0xdc, 0x8e, 0x3b, 0x27, 0xf3, 0xcc, 0x19, - 0x20, 0x9c, 0xc6, 0xa5, 0xec, 0xd8, 0x1d, 0x06, 0x17, 0x54, 0x3c, 0xb3, 0x4d, 0xd9, 0xad, 0xa8, - 0x52, 0x6c, 0x60, 0xa4, 0x63, 0x3a, 0x0a, 0x03, 0xc4, 0x74, 0xfc, 0xd3, 0x1c, 0x3c, 0xdb, 0x77, - 0x2d, 0x1d, 0x6c, 0x02, 0x3e, 0x79, 0xc1, 0x1c, 0xc7, 0x1b, 0x3b, 0x43, 0x86, 0x28, 0xfc, 0xa7, - 0x3e, 0x23, 0x4d, 0x84, 0x28, 0xa4, 0x97, 0x0a, 0x6b, 0xd8, 0xa5, 0xe2, 0x09, 0xea, 0xcf, 0xae, - 0xa8, 0x84, 0x91, 0x21, 0xa2, 0x12, 0x52, 0x1f, 0xa3, 0x30, 0xe0, 0x44, 0xfe, 0x6e, 0xff, 0xee, - 0xa5, 0xb6, 0xf7, 0x40, 0xa7, 0x3e, 0x8b, 0x70, 0x56, 0xbc, 0xd7, 0xbf, 0xd9, 0xde, 0x16, 0x11, - 0x9d, 0xb9, 0xe4, 0x93, 0x36, 0xcb, 0x29, 0x38, 0xee, 0xaa, 0xf1, 0x04, 0x46, 0x89, 0x1c, 0xb3, - 0x4b, 0x3f, 0x0e, 0x65, 0x45, 0x9b, 0x3b, 0x1c, 0xaa, 0x0f, 0xda, 0xe5, 0x70, 0xa8, 0xbe, 0xa6, - 0x81, 0x45, 0x7b, 0x62, 0x97, 0x74, 0xd2, 0x23, 0xf3, 0x26, 0xe9, 0xb0, 0xcb, 0x47, 0xfb, 0x27, - 0x60, 0x5c, 0x6d, 0x22, 0x07, 0xcd, 0x89, 0x69, 0xff, 0x8f, 0x11, 0x98, 0x48, 0x44, 0xee, 0x27, - 0x8e, 0x42, 0xac, 0x23, 0x8f, 0x42, 0x98, 0xd3, 0x67, 0xdb, 0x97, 0x59, 0x67, 0x0d, 0xa7, 0xcf, - 0xb6, 0x4f, 0x30, 0x87, 0xd1, 0xad, 0x7b, 0x35, 0xec, 0xe0, 0xb6, 0x2f, 0x1c, 0xbd, 0xd4, 0xd6, - 0x7d, 0x91, 0x95, 0x62, 0x01, 0x45, 0x9f, 0xb2, 0x60, 0x3c, 0x62, 0xe7, 0x6c, 0xfc, 0x20, 0x49, - 0x7c, 0xd0, 0x1b, 0x59, 0xbc, 0x36, 0x2a, 0xb2, 0x54, 0xb0, 0x3b, 0x62, 0xb3, 0x04, 0x27, 0x38, - 0xa2, 0xcf, 0x5a, 0xe6, 0x3b, 0xab, 0xc5, 0x2c, 0x1c, 0x14, 0xd3, 0x89, 0x11, 0xf8, 0x31, 0xcb, - 0xc3, 0x9f, 0x5b, 0x8d, 0xd4, 0x29, 0xcf, 0xe8, 0xe9, 0x9c, 0xf2, 0x40, 0x8f, 0x13, 0x9e, 0x0f, - 0x40, 0xb9, 0xe9, 0xf8, 0x5e, 0x8d, 0x44, 0x71, 0x34, 0x5d, 0x32, 0xf2, 0xb5, 0xc8, 0x42, 0xac, - 0xe1, 0x74, 0xb1, 0x8b, 0x58, 0xc3, 0xf8, 0xbd, 0x58, 0x59, 0x3f, 0x00, 0xb1, 0xa9, 0x8b, 0xb1, - 0x89, 0x63, 0xff, 0x63, 0x0b, 0x2e, 0xf4, 0xec, 0x8c, 0x27, 0xd7, 0xa3, 0x86, 0x2e, 0xd0, 0xe7, - 0x7a, 0x64, 0xb6, 0x40, 0x9d, 0x53, 0x7b, 0x8e, 0x57, 0xa4, 0xce, 0x98, 0xe8, 0x3b, 0x36, 0x86, - 0x3b, 0xab, 0xd4, 0xe7, 0x85, 0xf9, 0x47, 0x7a, 0x5e, 0x68, 0xbf, 0x9b, 0x07, 0xe3, 0xe1, 0x68, - 0xf4, 0x4b, 0x66, 0x12, 0x17, 0x2b, 0xab, 0x84, 0x23, 0x9c, 0xb8, 0x4a, 0x02, 0xc3, 0x7b, 0xad, - 0x57, 0x4e, 0x98, 0xf4, 0x78, 0xcd, 0x1d, 0x3d, 0x5e, 0x51, 0x43, 0x66, 0xcb, 0xc9, 0x67, 0x9f, - 0x2d, 0xa7, 0x9c, 0xce, 0x94, 0x83, 0x7e, 0xd7, 0x82, 0xe9, 0x66, 0x9f, 0xac, 0x6e, 0xd9, 0x04, - 0x31, 0xf7, 0xcb, 0x19, 0x57, 0x79, 0xfe, 0xf0, 0x60, 0xa6, 0x6f, 0x32, 0x3d, 0xdc, 0x57, 0x2a, - 0xfb, 0x6f, 0x5b, 0x7c, 0x72, 0xa4, 0xbe, 0x82, 0x5e, 0x14, 0xac, 0x87, 0x2c, 0x0a, 0x2f, 0xb3, - 0x37, 0x99, 0x6a, 0xd7, 0x89, 0xd3, 0x10, 0x8b, 0x87, 0xf9, 0xbc, 0x12, 0x2b, 0xc7, 0x0a, 0x83, - 0x65, 0x70, 0x6f, 0x34, 0x82, 0xfb, 0x57, 0x9b, 0xad, 0xb8, 0x23, 0x96, 0x11, 0x9d, 0xc1, 0x5d, - 0x41, 0xb0, 0x81, 0x65, 0xff, 0xb9, 0xc5, 0x47, 0xa0, 0xb8, 0xa9, 0x7a, 0x3d, 0x95, 0x2e, 0x78, - 0xf0, 0x4b, 0x9e, 0x5f, 0x00, 0x70, 0xd5, 0x73, 0x2c, 0xd9, 0x3c, 0x81, 0xad, 0x9f, 0x77, 0x31, - 0xdf, 0x65, 0x96, 0x65, 0xd8, 0xe0, 0x97, 0x98, 0xef, 0xf9, 0xa3, 0xe6, 0xbb, 0xfd, 0x67, 0x16, - 0x24, 0xd6, 0x37, 0xd4, 0x82, 0x02, 0x95, 0xa0, 0x93, 0xcd, 0xe3, 0x31, 0x26, 0x69, 0xaa, 0x0b, - 0xc4, 0x48, 0x66, 0x3f, 0x31, 0x67, 0x84, 0x1a, 0xe2, 0x8e, 0x2a, 0x97, 0xc5, 0x03, 0x47, 0x26, - 0xc3, 0xeb, 0x41, 0xb0, 0xcb, 0xcf, 0xe0, 0xf5, 0x7d, 0x97, 0xfd, 0x3a, 0x4c, 0x75, 0x09, 0xc5, - 0x92, 0x7d, 0x06, 0xf2, 0xc5, 0x1c, 0x63, 0x04, 0xb2, 0xd4, 0xc3, 0x98, 0xc3, 0xec, 0x6f, 0x59, - 0x70, 0x36, 0x4d, 0x1e, 0x7d, 0xdd, 0x82, 0xa9, 0x28, 0x4d, 0xef, 0xb4, 0xfa, 0x4e, 0xf9, 0x6f, - 0x74, 0x81, 0x70, 0xb7, 0x10, 0xf6, 0xff, 0xcf, 0xf1, 0xf1, 0x7c, 0xc7, 0xf3, 0xab, 0xc1, 0x7d, - 0xb5, 0x1e, 0x5a, 0x7d, 0xd7, 0x43, 0x3a, 0xc5, 0xdc, 0x1d, 0x52, 0x6d, 0x37, 0xba, 0x22, 0x54, - 0x36, 0x45, 0x39, 0x56, 0x18, 0x89, 0xe7, 0x69, 0xf3, 0x47, 0x3e, 0x4f, 0xfb, 0x1a, 0x8c, 0x9b, - 0xaf, 0x42, 0x89, 0xb8, 0x7d, 0x66, 0x5e, 0x99, 0x0f, 0x48, 0xe1, 0x04, 0x56, 0xea, 0x5d, 0xd0, - 0xc2, 0x91, 0xef, 0x82, 0xbe, 0x04, 0x25, 0xf1, 0xc6, 0xa5, 0xf4, 0x72, 0xe2, 0xe1, 0x2f, 0xa2, - 0x0c, 0x2b, 0x28, 0x55, 0x10, 0x4d, 0xc7, 0x6f, 0x3b, 0x0d, 0xda, 0x43, 0x22, 0xce, 0x4e, 0xcd, - 0xac, 0x55, 0x05, 0xc1, 0x06, 0x16, 0x6d, 0x71, 0xec, 0x35, 0xc9, 0xdb, 0x81, 0x2f, 0xfd, 0x03, - 0xf4, 0x09, 0xa5, 0x28, 0xc7, 0x0a, 0xc3, 0xfe, 0xef, 0x16, 0xa4, 0x1f, 0xe8, 0x4b, 0xec, 0x59, - 0xad, 0x23, 0x63, 0xfb, 0x92, 0x51, 0x46, 0xb9, 0x81, 0xa2, 0x8c, 0xcc, 0x00, 0xa0, 0xfc, 0x43, - 0x03, 0x80, 0x7e, 0x4c, 0xa7, 0x8c, 0xe7, 0x91, 0x42, 0x63, 0xbd, 0xd2, 0xc5, 0x23, 0x1b, 0x8a, - 0xae, 0xa3, 0x22, 0xb6, 0xc7, 0xb9, 0x25, 0xb8, 0x30, 0xcf, 0x90, 0x04, 0xa4, 0xb2, 0xfd, 0x9d, - 0xef, 0x5f, 0x7a, 0xea, 0xbb, 0xdf, 0xbf, 0xf4, 0xd4, 0x1f, 0x7f, 0xff, 0xd2, 0x53, 0x9f, 0x3a, - 0xbc, 0x64, 0x7d, 0xe7, 0xf0, 0x92, 0xf5, 0xdd, 0xc3, 0x4b, 0xd6, 0x1f, 0x1f, 0x5e, 0xb2, 0xde, - 0x3d, 0xbc, 0x64, 0x7d, 0xe5, 0xbf, 0x5c, 0x7a, 0xea, 0xed, 0x9e, 0xfe, 0x1c, 0xf4, 0xc7, 0x2b, - 0x6e, 0x75, 0x6e, 0xef, 0x0a, 0x73, 0x29, 0xa0, 0xb3, 0x61, 0xce, 0x18, 0x02, 0x73, 0x72, 0x36, - 0xfc, 0x45, 0x00, 0x00, 0x00, 0xff, 0xff, 0x7a, 0x75, 0xd9, 0x62, 0xd1, 0xb7, 0x00, 0x00, + // 9332 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x7d, 0x6d, 0x6c, 0x1c, 0x49, + 0x76, 0xd8, 0xf5, 0x7c, 0x71, 0xe6, 0xf1, 0x43, 0x62, 0x49, 0xda, 0xe5, 0x6a, 0x77, 0x45, 0xa1, + 0x17, 0xbe, 0x5b, 0xe7, 0x76, 0xc9, 0xac, 0xbc, 0x77, 0xd9, 0x78, 0xed, 0x3d, 0x73, 0x48, 0x89, + 0xa2, 0x44, 0x8a, 0xdc, 0x22, 0x25, 0xf9, 0xf6, 0x7c, 0x1f, 0xcd, 0x9e, 0x9a, 0x61, 0x8b, 0x33, + 0xdd, 0xa3, 0xee, 0x1e, 0x8a, 0xb3, 0xfe, 0xba, 0x3b, 0x9f, 0xed, 0x4b, 0xee, 0x63, 0x2f, 0xeb, + 0x1f, 0x39, 0x03, 0x41, 0x72, 0x39, 0x1b, 0x46, 0x8c, 0xe4, 0x10, 0x07, 0xf9, 0x91, 0x38, 0x41, + 0x80, 0xc4, 0xce, 0x8f, 0x0d, 0x1c, 0x20, 0x07, 0xc4, 0xf0, 0x39, 0xb1, 0x43, 0xef, 0x31, 0x08, + 0x12, 0x04, 0x88, 0x83, 0x7c, 0xfc, 0x89, 0x90, 0x1f, 0x46, 0x7d, 0x57, 0xf7, 0xcc, 0x88, 0x33, + 0x62, 0x53, 0xd2, 0x1d, 0xf6, 0xdf, 0xcc, 0x7b, 0xaf, 0xdf, 0x7b, 0x5d, 0x5d, 0xf5, 0xea, 0x55, + 0xd5, 0x7b, 0xaf, 0x60, 0xb5, 0xe1, 0xc5, 0x3b, 0x9d, 0xed, 0x39, 0x37, 0x68, 0xcd, 0x3b, 0x61, + 0x23, 0x68, 0x87, 0xc1, 0x1d, 0xf6, 0xe3, 0x65, 0xb7, 0x36, 0xbf, 0x77, 0x69, 0xbe, 0xbd, 0xdb, + 0x98, 0x77, 0xda, 0x5e, 0x34, 0xef, 0xb4, 0xdb, 0x4d, 0xcf, 0x75, 0x62, 0x2f, 0xf0, 0xe7, 0xf7, + 0x5e, 0x71, 0x9a, 0xed, 0x1d, 0xe7, 0x95, 0xf9, 0x06, 0xf1, 0x49, 0xe8, 0xc4, 0xa4, 0x36, 0xd7, + 0x0e, 0x83, 0x38, 0x40, 0x3f, 0xa1, 0xb9, 0xcd, 0x49, 0x6e, 0xec, 0xc7, 0x67, 0xdd, 0xda, 0xdc, + 0xde, 0xa5, 0xb9, 0xf6, 0x6e, 0x63, 0x8e, 0x72, 0x9b, 0x33, 0xb8, 0xcd, 0x49, 0x6e, 0xe7, 0x5f, + 0x36, 0x74, 0x69, 0x04, 0x8d, 0x60, 0x9e, 0x31, 0xdd, 0xee, 0xd4, 0xd9, 0x3f, 0xf6, 0x87, 0xfd, + 0xe2, 0xc2, 0xce, 0xdb, 0xbb, 0xaf, 0x45, 0x73, 0x5e, 0x40, 0xd5, 0x9b, 0x77, 0x83, 0x90, 0xcc, + 0xef, 0xf5, 0x28, 0x74, 0xfe, 0xaa, 0xa6, 0x21, 0xfb, 0x31, 0xf1, 0x23, 0x2f, 0xf0, 0xa3, 0x97, + 0xa9, 0x0a, 0x24, 0xdc, 0x23, 0xa1, 0xf9, 0x7a, 0x06, 0x41, 0x3f, 0x4e, 0xaf, 0x6a, 0x4e, 0x2d, + 0xc7, 0xdd, 0xf1, 0x7c, 0x12, 0x76, 0xf5, 0xe3, 0x2d, 0x12, 0x3b, 0xfd, 0x9e, 0x9a, 0x1f, 0xf4, + 0x54, 0xd8, 0xf1, 0x63, 0xaf, 0x45, 0x7a, 0x1e, 0xf8, 0xf8, 0x51, 0x0f, 0x44, 0xee, 0x0e, 0x69, + 0x39, 0xe9, 0xe7, 0xec, 0xbb, 0x30, 0xb9, 0x70, 0x7b, 0x73, 0xa1, 0x13, 0xef, 0x2c, 0x06, 0x7e, + 0xdd, 0x6b, 0xa0, 0x8f, 0xc1, 0xb8, 0xdb, 0xec, 0x44, 0x31, 0x09, 0x6f, 0x38, 0x2d, 0x32, 0x63, + 0x5d, 0xb4, 0x5e, 0xac, 0x54, 0xcf, 0xbc, 0x77, 0x30, 0xfb, 0xa1, 0xc3, 0x83, 0xd9, 0xf1, 0x45, + 0x8d, 0xc2, 0x26, 0x1d, 0xfa, 0x51, 0x18, 0x0b, 0x83, 0x26, 0x59, 0xc0, 0x37, 0x66, 0x72, 0xec, + 0x91, 0x53, 0xe2, 0x91, 0x31, 0xcc, 0xc1, 0x58, 0xe2, 0xed, 0x3f, 0xca, 0x01, 0x2c, 0xb4, 0xdb, + 0x1b, 0x61, 0x70, 0x87, 0xb8, 0x31, 0xfa, 0x1c, 0x94, 0x69, 0x2b, 0xd4, 0x9c, 0xd8, 0x61, 0xd2, + 0xc6, 0x2f, 0xfd, 0xe5, 0x39, 0xfe, 0x32, 0x73, 0xe6, 0xcb, 0xe8, 0x3e, 0x40, 0xa9, 0xe7, 0xf6, + 0x5e, 0x99, 0x5b, 0xdf, 0xa6, 0xcf, 0xaf, 0x91, 0xd8, 0xa9, 0x22, 0x21, 0x0c, 0x34, 0x0c, 0x2b, + 0xae, 0xc8, 0x87, 0x42, 0xd4, 0x26, 0x2e, 0x53, 0x6c, 0xfc, 0xd2, 0xea, 0xdc, 0x71, 0x3a, 0xdb, + 0x9c, 0xd6, 0x7c, 0xb3, 0x4d, 0xdc, 0xea, 0x84, 0x90, 0x5c, 0xa0, 0xff, 0x30, 0x93, 0x83, 0xf6, + 0xa0, 0x14, 0xc5, 0x4e, 0xdc, 0x89, 0x66, 0xf2, 0x4c, 0xe2, 0x8d, 0xcc, 0x24, 0x32, 0xae, 0xd5, + 0x29, 0x21, 0xb3, 0xc4, 0xff, 0x63, 0x21, 0xcd, 0xfe, 0x4f, 0x16, 0x4c, 0x69, 0xe2, 0x55, 0x2f, + 0x8a, 0xd1, 0xcf, 0xf4, 0x34, 0xee, 0xdc, 0x70, 0x8d, 0x4b, 0x9f, 0x66, 0x4d, 0x7b, 0x5a, 0x08, + 0x2b, 0x4b, 0x88, 0xd1, 0xb0, 0x2d, 0x28, 0x7a, 0x31, 0x69, 0x45, 0x33, 0xb9, 0x8b, 0xf9, 0x17, + 0xc7, 0x2f, 0x5d, 0xcd, 0xea, 0x3d, 0xab, 0x93, 0x42, 0x68, 0x71, 0x85, 0xb2, 0xc7, 0x5c, 0x8a, + 0xfd, 0xdb, 0x13, 0xe6, 0xfb, 0xd1, 0x06, 0x47, 0xaf, 0xc0, 0x78, 0x14, 0x74, 0x42, 0x97, 0x60, + 0xd2, 0x0e, 0xa2, 0x19, 0xeb, 0x62, 0x9e, 0x76, 0x3d, 0xda, 0x53, 0x37, 0x35, 0x18, 0x9b, 0x34, + 0xe8, 0xeb, 0x16, 0x4c, 0xd4, 0x48, 0x14, 0x7b, 0x3e, 0x93, 0x2f, 0x95, 0xdf, 0x3a, 0xb6, 0xf2, + 0x12, 0xb8, 0xa4, 0x99, 0x57, 0xcf, 0x8a, 0x17, 0x99, 0x30, 0x80, 0x11, 0x4e, 0xc8, 0xa7, 0x23, + 0xae, 0x46, 0x22, 0x37, 0xf4, 0xda, 0xf4, 0x3f, 0xeb, 0x33, 0xc6, 0x88, 0x5b, 0xd2, 0x28, 0x6c, + 0xd2, 0x21, 0x1f, 0x8a, 0x74, 0x44, 0x45, 0x33, 0x05, 0xa6, 0xff, 0xca, 0xf1, 0xf4, 0x17, 0x8d, + 0x4a, 0x07, 0xab, 0x6e, 0x7d, 0xfa, 0x2f, 0xc2, 0x5c, 0x0c, 0xfa, 0x9a, 0x05, 0x33, 0x62, 0xc4, + 0x63, 0xc2, 0x1b, 0xf4, 0xf6, 0x8e, 0x17, 0x93, 0xa6, 0x17, 0xc5, 0x33, 0x45, 0xa6, 0xc3, 0xfc, + 0x70, 0x7d, 0x6b, 0x39, 0x0c, 0x3a, 0xed, 0xeb, 0x9e, 0x5f, 0xab, 0x5e, 0x14, 0x92, 0x66, 0x16, + 0x07, 0x30, 0xc6, 0x03, 0x45, 0xa2, 0x5f, 0xb3, 0xe0, 0xbc, 0xef, 0xb4, 0x48, 0xd4, 0x76, 0xe8, + 0xa7, 0xe5, 0xe8, 0x6a, 0xd3, 0x71, 0x77, 0x99, 0x46, 0xa5, 0x87, 0xd3, 0xc8, 0x16, 0x1a, 0x9d, + 0xbf, 0x31, 0x90, 0x35, 0x7e, 0x80, 0x58, 0xf4, 0x1b, 0x16, 0x4c, 0x07, 0x61, 0x7b, 0xc7, 0xf1, + 0x49, 0x4d, 0x62, 0xa3, 0x99, 0x31, 0x36, 0xf4, 0x3e, 0x73, 0xbc, 0x4f, 0xb4, 0x9e, 0x66, 0xbb, + 0x16, 0xf8, 0x5e, 0x1c, 0x84, 0x9b, 0x24, 0x8e, 0x3d, 0xbf, 0x11, 0x55, 0xcf, 0x1d, 0x1e, 0xcc, + 0x4e, 0xf7, 0x50, 0xe1, 0x5e, 0x7d, 0xd0, 0xcf, 0xc2, 0x78, 0xd4, 0xf5, 0xdd, 0xdb, 0x9e, 0x5f, + 0x0b, 0xee, 0x45, 0x33, 0xe5, 0x2c, 0x86, 0xef, 0xa6, 0x62, 0x28, 0x06, 0xa0, 0x16, 0x80, 0x4d, + 0x69, 0xfd, 0x3f, 0x9c, 0xee, 0x4a, 0x95, 0xac, 0x3f, 0x9c, 0xee, 0x4c, 0x0f, 0x10, 0x8b, 0x7e, + 0xd5, 0x82, 0xc9, 0xc8, 0x6b, 0xf8, 0x4e, 0xdc, 0x09, 0xc9, 0x75, 0xd2, 0x8d, 0x66, 0x80, 0x29, + 0x72, 0xed, 0x98, 0xad, 0x62, 0xb0, 0xac, 0x9e, 0x13, 0x3a, 0x4e, 0x9a, 0xd0, 0x08, 0x27, 0xe5, + 0xf6, 0x1b, 0x68, 0xba, 0x5b, 0x8f, 0x67, 0x3b, 0xd0, 0x74, 0xa7, 0x1e, 0x28, 0x12, 0xfd, 0x14, + 0x9c, 0xe6, 0x20, 0xd5, 0xb2, 0xd1, 0xcc, 0x04, 0x33, 0xb4, 0x67, 0x0f, 0x0f, 0x66, 0x4f, 0x6f, + 0xa6, 0x70, 0xb8, 0x87, 0x1a, 0xdd, 0x85, 0xd9, 0x36, 0x09, 0x5b, 0x5e, 0xbc, 0xee, 0x37, 0xbb, + 0xd2, 0x7c, 0xbb, 0x41, 0x9b, 0xd4, 0x84, 0x3a, 0xd1, 0xcc, 0xe4, 0x45, 0xeb, 0xc5, 0x72, 0xf5, + 0x23, 0x42, 0xcd, 0xd9, 0x8d, 0x07, 0x93, 0xe3, 0xa3, 0xf8, 0xd9, 0xff, 0x26, 0x07, 0xa7, 0xd3, + 0x13, 0x27, 0xfa, 0x2d, 0x0b, 0x4e, 0xdd, 0xb9, 0x17, 0x6f, 0x05, 0xbb, 0xc4, 0x8f, 0xaa, 0x5d, + 0x6a, 0xde, 0xd8, 0x94, 0x31, 0x7e, 0xc9, 0xcd, 0x76, 0x8a, 0x9e, 0xbb, 0x96, 0x94, 0x72, 0xd9, + 0x8f, 0xc3, 0x6e, 0xf5, 0x69, 0xf1, 0x76, 0xa7, 0xae, 0xdd, 0xde, 0x32, 0xb1, 0x38, 0xad, 0xd4, + 0xf9, 0xaf, 0x58, 0x70, 0xb6, 0x1f, 0x0b, 0x74, 0x1a, 0xf2, 0xbb, 0xa4, 0xcb, 0xbd, 0x32, 0x4c, + 0x7f, 0xa2, 0x4f, 0x43, 0x71, 0xcf, 0x69, 0x76, 0x88, 0xf0, 0x6e, 0x96, 0x8f, 0xf7, 0x22, 0x4a, + 0x33, 0xcc, 0xb9, 0xfe, 0x78, 0xee, 0x35, 0xcb, 0xfe, 0x77, 0x79, 0x18, 0x37, 0xe6, 0xb7, 0x47, + 0xe0, 0xb1, 0x05, 0x09, 0x8f, 0x6d, 0x2d, 0xb3, 0xa9, 0x79, 0xa0, 0xcb, 0x76, 0x2f, 0xe5, 0xb2, + 0xad, 0x67, 0x27, 0xf2, 0x81, 0x3e, 0x1b, 0x8a, 0xa1, 0x12, 0xb4, 0xa9, 0x47, 0x4e, 0xa7, 0xfe, + 0x42, 0x16, 0x9f, 0x70, 0x5d, 0xb2, 0xab, 0x4e, 0x1e, 0x1e, 0xcc, 0x56, 0xd4, 0x5f, 0xac, 0x05, + 0xd9, 0xdf, 0xb3, 0xe0, 0xac, 0xa1, 0xe3, 0x62, 0xe0, 0xd7, 0x3c, 0xf6, 0x69, 0x2f, 0x42, 0x21, + 0xee, 0xb6, 0xa5, 0xdb, 0xaf, 0x5a, 0x6a, 0xab, 0xdb, 0x26, 0x98, 0x61, 0xa8, 0xa3, 0xdf, 0x22, + 0x51, 0xe4, 0x34, 0x48, 0xda, 0xd1, 0x5f, 0xe3, 0x60, 0x2c, 0xf1, 0x28, 0x04, 0xd4, 0x74, 0xa2, + 0x78, 0x2b, 0x74, 0xfc, 0x88, 0xb1, 0xdf, 0xf2, 0x5a, 0x44, 0x34, 0xf0, 0x5f, 0x1a, 0xae, 0xc7, + 0xd0, 0x27, 0xaa, 0x4f, 0x1d, 0x1e, 0xcc, 0xa2, 0xd5, 0x1e, 0x4e, 0xb8, 0x0f, 0x77, 0xfb, 0xd7, + 0x2c, 0x78, 0xaa, 0xbf, 0x2f, 0x86, 0x3e, 0x0c, 0x25, 0xbe, 0x7a, 0x13, 0x6f, 0xa7, 0x3f, 0x09, + 0x83, 0x62, 0x81, 0x45, 0xf3, 0x50, 0x51, 0xf3, 0x84, 0x78, 0xc7, 0x69, 0x41, 0x5a, 0xd1, 0x93, + 0x8b, 0xa6, 0xa1, 0x8d, 0x46, 0xff, 0x08, 0xcf, 0x4d, 0x35, 0x1a, 0x5b, 0x24, 0x31, 0x8c, 0xfd, + 0x67, 0x16, 0x9c, 0x32, 0xb4, 0x7a, 0x04, 0xae, 0xb9, 0x9f, 0x74, 0xcd, 0x57, 0x32, 0xeb, 0xcf, + 0x03, 0x7c, 0xf3, 0xc3, 0x1c, 0xf3, 0xcd, 0x55, 0xaf, 0x27, 0x8f, 0x62, 0x61, 0x17, 0x26, 0xcc, + 0xc4, 0x46, 0x76, 0x63, 0x96, 0x0c, 0x5e, 0xdc, 0xbd, 0x9d, 0xb2, 0x14, 0x38, 0x53, 0xa9, 0x0f, + 0x5e, 0xe0, 0xfd, 0xf7, 0x1c, 0x3c, 0x9d, 0x7c, 0x40, 0x8f, 0xdc, 0x4f, 0x24, 0x46, 0xee, 0x47, + 0xcd, 0x91, 0x7b, 0xff, 0x60, 0xf6, 0xd9, 0x01, 0x8f, 0xfd, 0xc0, 0x0c, 0x6c, 0xb4, 0xac, 0xda, + 0xbd, 0xc0, 0xb4, 0x9b, 0x4f, 0xb6, 0xd1, 0xfd, 0x83, 0xd9, 0xe7, 0x07, 0xbc, 0x63, 0xca, 0xe2, + 0x7e, 0x18, 0x4a, 0x21, 0x71, 0xa2, 0xc0, 0x9f, 0x29, 0x26, 0xcd, 0x00, 0x66, 0x50, 0x2c, 0xb0, + 0xf6, 0x9f, 0x95, 0xd3, 0x8d, 0xbd, 0xcc, 0xf7, 0x4e, 0x82, 0x10, 0x79, 0x50, 0x60, 0xde, 0x18, + 0xef, 0xd6, 0xd7, 0x8f, 0xd7, 0x05, 0xe8, 0xe8, 0x55, 0xac, 0xab, 0x65, 0xfa, 0xd5, 0x28, 0x08, + 0x33, 0x11, 0x68, 0x1f, 0xca, 0xae, 0x74, 0x92, 0x72, 0x59, 0x6c, 0x27, 0x08, 0x17, 0x49, 0x4b, + 0x9c, 0xa0, 0x26, 0x44, 0x79, 0x56, 0x4a, 0x1a, 0x22, 0x90, 0x6f, 0x78, 0xb1, 0xf8, 0xac, 0xc7, + 0x74, 0x83, 0x97, 0x3d, 0xe3, 0x15, 0xc7, 0x0e, 0x0f, 0x66, 0xf3, 0xcb, 0x5e, 0x8c, 0x29, 0x7f, + 0xf4, 0xcb, 0x16, 0x8c, 0x47, 0x6e, 0x6b, 0x23, 0x0c, 0xf6, 0xbc, 0x1a, 0x09, 0xc5, 0x24, 0x78, + 0xcc, 0x61, 0xb5, 0xb9, 0xb8, 0x26, 0x19, 0x6a, 0xb9, 0x7c, 0x59, 0xa2, 0x31, 0xd8, 0x94, 0x4b, + 0x9d, 0xc3, 0xa7, 0xc5, 0xbb, 0x2f, 0x11, 0xd7, 0x8b, 0xe8, 0x94, 0x29, 0x7c, 0x61, 0xd6, 0x53, + 0x8e, 0xed, 0x14, 0x2c, 0x75, 0xdc, 0x5d, 0x3a, 0xde, 0xb4, 0x42, 0xcf, 0x1e, 0x1e, 0xcc, 0x3e, + 0xbd, 0xd8, 0x5f, 0x26, 0x1e, 0xa4, 0x0c, 0x6b, 0xb0, 0x76, 0xa7, 0xd9, 0xc4, 0xe4, 0x6e, 0x87, + 0xb0, 0x95, 0x6e, 0x06, 0x0d, 0xb6, 0xa1, 0x19, 0xa6, 0x1a, 0xcc, 0xc0, 0x60, 0x53, 0x2e, 0xba, + 0x0b, 0xa5, 0x96, 0x13, 0x87, 0xde, 0xbe, 0x58, 0xde, 0x1e, 0xd3, 0x4d, 0x5b, 0x63, 0xbc, 0xb4, + 0x70, 0xa0, 0x63, 0x92, 0x03, 0xb1, 0x10, 0x84, 0x5a, 0x50, 0x6c, 0x91, 0xb0, 0x41, 0x66, 0xca, + 0x59, 0x6c, 0xe5, 0xad, 0x51, 0x56, 0x5a, 0x60, 0x85, 0x4e, 0x6a, 0x0c, 0x86, 0xb9, 0x14, 0xf4, + 0x69, 0x28, 0x47, 0xa4, 0x49, 0xdc, 0x38, 0x08, 0x67, 0x2a, 0x4c, 0xe2, 0x8f, 0x0d, 0x39, 0x45, + 0x3b, 0xdb, 0xa4, 0xb9, 0x29, 0x1e, 0xe5, 0x03, 0x4c, 0xfe, 0xc3, 0x8a, 0xa5, 0xfd, 0x5f, 0x2c, + 0x40, 0x49, 0x0b, 0xf3, 0x08, 0x1c, 0x83, 0xbb, 0x49, 0xc7, 0x60, 0x35, 0xcb, 0xe9, 0x6b, 0x80, + 0x6f, 0xf0, 0x5e, 0x19, 0x52, 0xb6, 0xf9, 0x06, 0x89, 0x62, 0x52, 0xfb, 0xc0, 0x9e, 0x7e, 0x60, + 0x4f, 0x3f, 0xb0, 0xa7, 0xca, 0x9e, 0x6e, 0xa7, 0xec, 0xe9, 0x1b, 0xc6, 0xa8, 0xd7, 0x67, 0x4c, + 0x9f, 0x55, 0x87, 0x50, 0xa6, 0x06, 0x06, 0x01, 0xb5, 0x04, 0xd7, 0x36, 0xd7, 0x6f, 0xf4, 0x35, + 0xa0, 0x9f, 0x4d, 0x1a, 0xd0, 0xe3, 0x8a, 0x78, 0xe4, 0x26, 0xf3, 0x30, 0x9f, 0x36, 0x99, 0xec, + 0x18, 0xe0, 0x12, 0x40, 0x23, 0xd8, 0x22, 0xad, 0x76, 0xd3, 0x89, 0xb9, 0x0b, 0x5c, 0xd6, 0x4b, + 0x87, 0x65, 0x85, 0xc1, 0x06, 0x15, 0xfa, 0x6b, 0x16, 0x40, 0x43, 0x7e, 0x1a, 0x69, 0x0e, 0x6f, + 0x66, 0x69, 0x0e, 0xf5, 0x87, 0xd7, 0xba, 0x28, 0x81, 0xd8, 0x10, 0x8e, 0xbe, 0x68, 0x41, 0x39, + 0x96, 0xea, 0x73, 0x03, 0xb1, 0x95, 0xa5, 0x26, 0xf2, 0xa5, 0xf5, 0xcc, 0xa0, 0x9a, 0x44, 0xc9, + 0x45, 0xbf, 0x62, 0x01, 0x44, 0x5d, 0xdf, 0xdd, 0x08, 0x9a, 0x9e, 0xdb, 0x15, 0x76, 0xe3, 0x56, + 0xa6, 0xcb, 0x1b, 0xc5, 0xbd, 0x3a, 0x45, 0x5b, 0x43, 0xff, 0xc7, 0x86, 0x64, 0xfb, 0xdb, 0xc9, + 0xdd, 0x09, 0xb5, 0x2e, 0x62, 0x9f, 0xcc, 0x95, 0x6e, 0x7d, 0x24, 0xb6, 0xee, 0x32, 0xfd, 0x64, + 0x6a, 0xd1, 0xa0, 0x3f, 0x99, 0x02, 0x45, 0xd8, 0x10, 0x6e, 0x7f, 0xc1, 0x82, 0x99, 0x41, 0x6f, + 0x87, 0x08, 0x3c, 0xdb, 0x0e, 0x09, 0x1b, 0x43, 0x6a, 0xd3, 0x7d, 0xdd, 0x5f, 0x22, 0x4d, 0xc2, + 0xf6, 0x79, 0x78, 0x07, 0x7d, 0x41, 0x48, 0x78, 0x76, 0x63, 0x30, 0x29, 0x7e, 0x10, 0x1f, 0xfb, + 0x37, 0x73, 0x89, 0xcd, 0x0e, 0xe3, 0x43, 0xa3, 0x6f, 0x5a, 0x3d, 0x5e, 0xc4, 0x4f, 0x9f, 0x44, + 0x8f, 0x62, 0xfe, 0x86, 0xda, 0x7b, 0x1f, 0x4c, 0xf3, 0x18, 0x37, 0xf7, 0xec, 0x7f, 0x5b, 0x80, + 0x07, 0x68, 0xa6, 0xb6, 0x6f, 0xac, 0x41, 0xdb, 0x37, 0xa3, 0xef, 0x08, 0x7d, 0xd5, 0x82, 0x52, + 0x93, 0x1a, 0xb4, 0x68, 0x26, 0xcf, 0x3a, 0x69, 0xed, 0xa4, 0xda, 0x9e, 0xdb, 0xcd, 0x88, 0x6f, + 0x30, 0xab, 0xa5, 0x2c, 0x07, 0x62, 0xa1, 0x03, 0xfa, 0x96, 0x05, 0xe3, 0x8e, 0xef, 0x07, 0xb1, + 0x38, 0xf1, 0xe4, 0x27, 0x86, 0xde, 0x89, 0xe9, 0xb4, 0xa0, 0x65, 0x71, 0xc5, 0xd4, 0x69, 0xa6, + 0x81, 0xc1, 0xa6, 0x4a, 0x68, 0x0e, 0xa0, 0xee, 0xf9, 0x4e, 0xd3, 0x7b, 0x9b, 0x3a, 0x66, 0x45, + 0x76, 0xbc, 0xc0, 0x6c, 0xc4, 0x15, 0x05, 0xc5, 0x06, 0xc5, 0xf9, 0xbf, 0x0a, 0xe3, 0xc6, 0x9b, + 0xf7, 0xd9, 0x17, 0x3f, 0x6b, 0xee, 0x8b, 0x57, 0x8c, 0xed, 0xec, 0xf3, 0x6f, 0xc0, 0xe9, 0xb4, + 0x82, 0xa3, 0x3c, 0x6f, 0xff, 0x56, 0x09, 0x66, 0xd3, 0x2f, 0x1f, 0xb6, 0xa8, 0x6a, 0x1f, 0x38, + 0xb4, 0x1f, 0x38, 0xb4, 0x1f, 0x38, 0xb4, 0xf2, 0x8f, 0x7d, 0x58, 0x84, 0x69, 0x73, 0xa0, 0x70, + 0xed, 0x7e, 0x14, 0xc6, 0x42, 0xd2, 0x0e, 0x6e, 0xe2, 0x55, 0x61, 0x71, 0x75, 0xa4, 0x10, 0x07, + 0x63, 0x89, 0xa7, 0x96, 0xb9, 0xed, 0xc4, 0x3b, 0xc2, 0xe4, 0x2a, 0xcb, 0xbc, 0xe1, 0xc4, 0x3b, + 0x98, 0x61, 0xd0, 0x1b, 0x30, 0x15, 0x3b, 0x61, 0x83, 0xc4, 0x98, 0xec, 0xb1, 0x46, 0x10, 0xbb, + 0x83, 0x4f, 0x09, 0xda, 0xa9, 0xad, 0x04, 0x16, 0xa7, 0xa8, 0xd1, 0x5d, 0x28, 0xec, 0x90, 0x66, + 0x4b, 0x78, 0xdc, 0x9b, 0xd9, 0x59, 0x44, 0xf6, 0xae, 0x57, 0x49, 0xb3, 0xc5, 0xc7, 0x2b, 0xfd, + 0x85, 0x99, 0x28, 0xfa, 0x75, 0x2a, 0xbb, 0x9d, 0x28, 0x0e, 0x5a, 0xde, 0xdb, 0xd2, 0x0f, 0xff, + 0xe9, 0x8c, 0x05, 0x5f, 0x97, 0xfc, 0xf9, 0x19, 0x90, 0xfa, 0x8b, 0xb5, 0x64, 0xa6, 0x47, 0xcd, + 0x0b, 0x99, 0x5f, 0xdd, 0x9d, 0x81, 0x13, 0xd1, 0x63, 0x49, 0xf2, 0xe7, 0x7a, 0xa8, 0xbf, 0x58, + 0x4b, 0x46, 0x5d, 0x28, 0xb5, 0x9b, 0x9d, 0x86, 0xe7, 0xcf, 0x8c, 0x33, 0x1d, 0x6e, 0x66, 0xac, + 0xc3, 0x06, 0x63, 0xce, 0x57, 0x43, 0xfc, 0x37, 0x16, 0x02, 0xd1, 0x0b, 0x50, 0x74, 0x77, 0x9c, + 0x30, 0x9e, 0x99, 0x60, 0x9d, 0x46, 0xed, 0x5e, 0x2c, 0x52, 0x20, 0xe6, 0x38, 0xf4, 0x3c, 0xe4, + 0x43, 0x52, 0x67, 0x07, 0xd4, 0x95, 0xea, 0xb8, 0x20, 0xc9, 0x63, 0x52, 0xc7, 0x14, 0x6e, 0xff, + 0xdd, 0x5c, 0xd2, 0xb9, 0x48, 0xbe, 0x37, 0xef, 0xed, 0x6e, 0x27, 0x8c, 0xe4, 0xb2, 0xc4, 0xe8, + 0xed, 0x0c, 0x8c, 0x25, 0x1e, 0x7d, 0xc1, 0x82, 0xb1, 0x3b, 0x51, 0xe0, 0xfb, 0x24, 0x16, 0x86, + 0xfc, 0x56, 0xc6, 0x4d, 0x71, 0x8d, 0x73, 0xd7, 0x3a, 0x08, 0x00, 0x96, 0x72, 0xa9, 0xba, 0x64, + 0xdf, 0x6d, 0x76, 0x6a, 0xf2, 0x34, 0x4b, 0x91, 0x5e, 0xe6, 0x60, 0x2c, 0xf1, 0x94, 0xd4, 0xf3, + 0x39, 0x69, 0x21, 0x49, 0xba, 0xe2, 0x0b, 0x52, 0x81, 0xb7, 0x7f, 0xa7, 0x08, 0xe7, 0xfa, 0x0e, + 0x0e, 0x3a, 0xed, 0xb3, 0x89, 0xf5, 0x8a, 0xd7, 0x24, 0x32, 0x7c, 0x8b, 0x4d, 0xfb, 0xb7, 0x14, + 0x14, 0x1b, 0x14, 0xe8, 0x17, 0x01, 0xda, 0x4e, 0xe8, 0xb4, 0x88, 0x98, 0xee, 0xf2, 0xc7, 0x9f, + 0x5d, 0xa9, 0x1e, 0x1b, 0x92, 0xa7, 0x76, 0xfb, 0x15, 0x28, 0xc2, 0x86, 0x48, 0xf4, 0x31, 0x18, + 0x0f, 0x49, 0x93, 0x38, 0x11, 0x8b, 0x6f, 0x48, 0x07, 0x6b, 0x61, 0x8d, 0xc2, 0x26, 0x1d, 0xfa, + 0x30, 0x94, 0xd8, 0x5b, 0xc8, 0xd3, 0x0b, 0xe5, 0xa9, 0xb1, 0xf7, 0x8c, 0xb0, 0xc0, 0xa2, 0x77, + 0x2c, 0x98, 0xaa, 0x7b, 0x4d, 0xa2, 0xa5, 0x8b, 0xd0, 0xaa, 0xf5, 0xe3, 0xbf, 0xe4, 0x15, 0x93, + 0xaf, 0xb6, 0x90, 0x09, 0x70, 0x84, 0x53, 0xe2, 0xe9, 0x67, 0xde, 0x23, 0x21, 0x33, 0xad, 0xa5, + 0xe4, 0x67, 0xbe, 0xc5, 0xc1, 0x58, 0xe2, 0xd1, 0x02, 0x9c, 0x6a, 0x3b, 0x51, 0xb4, 0x18, 0x92, + 0x1a, 0xf1, 0x63, 0xcf, 0x69, 0xf2, 0xc0, 0xa7, 0xb2, 0x0e, 0x7c, 0xd8, 0x48, 0xa2, 0x71, 0x9a, + 0x1e, 0x7d, 0x12, 0x9e, 0xf6, 0x1a, 0x7e, 0x10, 0x92, 0x35, 0x2f, 0x8a, 0x3c, 0xbf, 0xa1, 0xbb, + 0x01, 0xb3, 0x94, 0xe5, 0xea, 0xac, 0x60, 0xf5, 0xf4, 0x4a, 0x7f, 0x32, 0x3c, 0xe8, 0x79, 0xf4, + 0x12, 0x94, 0xa3, 0x5d, 0xaf, 0xbd, 0x18, 0xd6, 0x22, 0xb6, 0x33, 0x51, 0xd6, 0x8b, 0xe1, 0x4d, + 0x01, 0xc7, 0x8a, 0xc2, 0xfe, 0xf5, 0x5c, 0x72, 0x79, 0x67, 0x8e, 0x1f, 0x14, 0xd1, 0x51, 0x12, + 0xdf, 0x72, 0x42, 0xb9, 0x06, 0x3d, 0x66, 0xe8, 0x94, 0xe0, 0x7b, 0xcb, 0x09, 0xcd, 0xf1, 0xc6, + 0x04, 0x60, 0x29, 0x09, 0xdd, 0x81, 0x42, 0xdc, 0x74, 0x32, 0x8a, 0xb5, 0x34, 0x24, 0xea, 0x43, + 0xfe, 0xd5, 0x85, 0x08, 0x33, 0x19, 0xe8, 0x39, 0xea, 0xbe, 0x6e, 0xf3, 0xc5, 0x4b, 0x45, 0x7a, + 0x9c, 0xdb, 0x11, 0x66, 0x50, 0xfb, 0x7f, 0x96, 0xfa, 0x98, 0x3c, 0x35, 0xc7, 0xa0, 0x4b, 0x00, + 0x74, 0x25, 0xb4, 0x11, 0x92, 0xba, 0xb7, 0x2f, 0xe6, 0x78, 0x35, 0xac, 0x6e, 0x28, 0x0c, 0x36, + 0xa8, 0xe4, 0x33, 0x9b, 0x9d, 0x3a, 0x7d, 0x26, 0xd7, 0xfb, 0x0c, 0xc7, 0x60, 0x83, 0x0a, 0xbd, + 0x0a, 0x25, 0xaf, 0xe5, 0x34, 0x88, 0x54, 0xf3, 0x39, 0x3a, 0x9e, 0x56, 0x18, 0xe4, 0xfe, 0xc1, + 0xec, 0x94, 0x52, 0x88, 0x81, 0xb0, 0xa0, 0x45, 0xbf, 0x69, 0xc1, 0x84, 0x1b, 0xb4, 0x5a, 0x81, + 0xcf, 0xd7, 0x0f, 0x62, 0x31, 0x74, 0xe7, 0xa4, 0x66, 0xe0, 0xb9, 0x45, 0x43, 0x18, 0x5f, 0x0d, + 0xa9, 0xa0, 0x50, 0x13, 0x85, 0x13, 0x5a, 0x99, 0xc3, 0xae, 0x78, 0xc4, 0xb0, 0xfb, 0xa7, 0x16, + 0x4c, 0xf3, 0x67, 0x8d, 0x65, 0x8d, 0x88, 0x7f, 0x0c, 0x4e, 0xf8, 0xb5, 0x7a, 0x56, 0x7a, 0xcf, + 0x08, 0x35, 0xa7, 0x7b, 0xf0, 0xb8, 0x57, 0x49, 0xb4, 0x0c, 0xd3, 0xf5, 0x20, 0x74, 0x89, 0xd9, + 0x10, 0xc2, 0x66, 0x28, 0x46, 0x57, 0xd2, 0x04, 0xb8, 0xf7, 0x19, 0x74, 0x0b, 0x9e, 0x32, 0x80, + 0x66, 0x3b, 0x70, 0xb3, 0x71, 0x41, 0x70, 0x7b, 0xea, 0x4a, 0x5f, 0x2a, 0x3c, 0xe0, 0xe9, 0xf3, + 0x9f, 0x80, 0xe9, 0x9e, 0xef, 0x37, 0xd2, 0x62, 0x73, 0x09, 0x9e, 0xea, 0xdf, 0x52, 0x23, 0x2d, + 0x39, 0xff, 0x71, 0xea, 0xe0, 0xdf, 0x70, 0x6c, 0x86, 0xd8, 0xbe, 0x70, 0x20, 0x4f, 0xfc, 0x3d, + 0x61, 0x38, 0xae, 0x1c, 0xaf, 0x47, 0x5c, 0xf6, 0xf7, 0xf8, 0x87, 0x66, 0x6b, 0xb4, 0xcb, 0xfe, + 0x1e, 0xa6, 0xbc, 0xd1, 0xbb, 0x56, 0x62, 0x62, 0xe6, 0x9b, 0x1e, 0x9f, 0x39, 0x11, 0x4f, 0x6e, + 0xe8, 0xb9, 0xda, 0xfe, 0x83, 0x1c, 0x5c, 0x3c, 0x8a, 0xc9, 0x10, 0xcd, 0xf7, 0x02, 0x94, 0xa2, + 0x38, 0xf4, 0xfc, 0x86, 0x18, 0x89, 0xe3, 0x74, 0x14, 0x6e, 0x32, 0xc8, 0x67, 0xb1, 0x40, 0xa1, + 0x5f, 0xb1, 0x20, 0xdf, 0x72, 0xda, 0xe2, 0xcd, 0x1b, 0x27, 0xfb, 0xe6, 0x73, 0x6b, 0x4e, 0x9b, + 0x7f, 0x05, 0xe5, 0x8f, 0xae, 0x39, 0x6d, 0x4c, 0x15, 0x40, 0xb3, 0x50, 0x74, 0xc2, 0xd0, 0xe9, + 0x32, 0xbb, 0x56, 0xe1, 0x3b, 0xf4, 0x0b, 0x14, 0x80, 0x39, 0xfc, 0xfc, 0xc7, 0xa1, 0x2c, 0x1f, + 0x1f, 0xa9, 0x0f, 0x7e, 0x75, 0x2c, 0x11, 0xc3, 0xc4, 0xf6, 0xdd, 0x23, 0x28, 0x89, 0x05, 0xb0, + 0x95, 0x75, 0xd8, 0x1c, 0x0f, 0x42, 0x65, 0x5e, 0xbb, 0x08, 0xe5, 0x17, 0xa2, 0xd0, 0x57, 0x2c, + 0x16, 0x30, 0x2f, 0xe3, 0xba, 0x84, 0xaf, 0x7c, 0x32, 0xf1, 0xfb, 0x66, 0x18, 0xbe, 0x04, 0x62, + 0x53, 0x3a, 0x35, 0xd4, 0x6d, 0x1e, 0xfa, 0x99, 0xf6, 0x98, 0x65, 0x48, 0xbd, 0xc4, 0xa3, 0xfd, + 0x3e, 0xfb, 0xeb, 0x19, 0x04, 0x5d, 0x1f, 0xbd, 0xa3, 0x8e, 0xbe, 0x65, 0xc1, 0x34, 0xf7, 0x8b, + 0x96, 0xbc, 0x7a, 0x9d, 0x84, 0xc4, 0x77, 0x89, 0xf4, 0x2c, 0x6f, 0x1f, 0x4f, 0x03, 0xb9, 0xeb, + 0xb0, 0x92, 0x66, 0xaf, 0x2d, 0x78, 0x0f, 0x0a, 0xf7, 0x2a, 0x83, 0x6a, 0x50, 0xf0, 0xfc, 0x7a, + 0x20, 0xe6, 0xad, 0xea, 0xf1, 0x94, 0x5a, 0xf1, 0xeb, 0x81, 0x1e, 0xcb, 0xf4, 0x1f, 0x66, 0xdc, + 0xd1, 0x2a, 0x9c, 0x0d, 0xc5, 0xda, 0xff, 0xaa, 0x17, 0xd1, 0x15, 0xda, 0xaa, 0xd7, 0xf2, 0x62, + 0x36, 0xe7, 0xe4, 0xab, 0x33, 0x87, 0x07, 0xb3, 0x67, 0x71, 0x1f, 0x3c, 0xee, 0xfb, 0x14, 0x7a, + 0x1b, 0xc6, 0x64, 0x84, 0x7f, 0x39, 0x0b, 0x2f, 0xbd, 0xb7, 0xff, 0xab, 0xce, 0xb4, 0x29, 0x82, + 0xf9, 0xa5, 0x40, 0xfb, 0x5f, 0x42, 0x72, 0x73, 0x85, 0x9f, 0x90, 0xfc, 0x3c, 0x54, 0x42, 0x95, + 0x75, 0x60, 0x65, 0x71, 0xc2, 0x2f, 0xbf, 0xaf, 0x08, 0x4d, 0x53, 0xfb, 0xde, 0x3a, 0xbf, 0x40, + 0x4b, 0xa4, 0x3e, 0x2a, 0xed, 0x75, 0x62, 0x48, 0x66, 0xd0, 0xb7, 0x85, 0x54, 0xbd, 0xab, 0xdf, + 0xf5, 0x5d, 0xcc, 0x64, 0xa0, 0x10, 0x4a, 0x3b, 0xc4, 0x69, 0xc6, 0x3b, 0xd9, 0x6c, 0x40, 0x5e, + 0x65, 0xbc, 0xd2, 0x01, 0x78, 0x1c, 0x8a, 0x85, 0x24, 0xb4, 0x0f, 0x63, 0x3b, 0xbc, 0x03, 0x08, + 0xb7, 0x71, 0xed, 0xb8, 0x8d, 0x9b, 0xe8, 0x55, 0xfa, 0x73, 0x0b, 0x00, 0x96, 0xe2, 0xd8, 0xe1, + 0x9c, 0x71, 0xf4, 0xc5, 0x87, 0x6e, 0x76, 0xb1, 0x87, 0x43, 0x9f, 0x7b, 0xa1, 0xcf, 0xc1, 0x44, + 0x48, 0xdc, 0xc0, 0x77, 0xbd, 0x26, 0xa9, 0x2d, 0xc8, 0xcd, 0xc5, 0x51, 0xa2, 0xfe, 0x4e, 0x53, + 0xd7, 0x17, 0x1b, 0x3c, 0x70, 0x82, 0x23, 0xfa, 0xb2, 0x05, 0x53, 0x2a, 0x54, 0x99, 0x7e, 0x10, + 0x22, 0xb6, 0xe7, 0x56, 0x33, 0x0a, 0x8c, 0x66, 0x3c, 0xab, 0x88, 0x2e, 0x7e, 0x93, 0x30, 0x9c, + 0x92, 0x8b, 0xde, 0x02, 0x08, 0xb6, 0xd9, 0xf1, 0x1b, 0x7d, 0xd5, 0xf2, 0xc8, 0xaf, 0x3a, 0xc5, + 0x43, 0x57, 0x25, 0x07, 0x6c, 0x70, 0x43, 0xd7, 0x01, 0xf8, 0xb0, 0xd9, 0xea, 0xb6, 0x09, 0x5b, + 0x91, 0xea, 0xb0, 0x4d, 0xd8, 0x54, 0x98, 0xfb, 0x07, 0xb3, 0xbd, 0x7b, 0x27, 0x2c, 0x6c, 0xd3, + 0x78, 0x1c, 0xfd, 0x2c, 0x8c, 0x45, 0x9d, 0x56, 0xcb, 0x51, 0x3b, 0x79, 0x19, 0x06, 0xc3, 0x72, + 0xbe, 0x86, 0x29, 0xe2, 0x00, 0x2c, 0x25, 0xa2, 0x3b, 0xd4, 0xa8, 0x46, 0x62, 0x53, 0x87, 0x8d, + 0x22, 0xee, 0x13, 0x8c, 0xb3, 0x77, 0xfa, 0xb8, 0x78, 0xee, 0x2c, 0xee, 0x43, 0x73, 0xff, 0x60, + 0xf6, 0xa9, 0x24, 0x7c, 0x35, 0xe0, 0x62, 0x71, 0x5f, 0x9e, 0xe8, 0x9a, 0x4c, 0xf8, 0xa3, 0xaf, + 0x2d, 0xf3, 0x50, 0x5e, 0xd4, 0x09, 0x7f, 0x0c, 0x3c, 0xb8, 0xcd, 0xcc, 0x87, 0x6d, 0x3f, 0x19, + 0x4b, 0x20, 0xde, 0xe6, 0x55, 0x98, 0x20, 0xfb, 0x31, 0x09, 0x7d, 0xa7, 0x79, 0x13, 0xaf, 0xca, + 0x4d, 0x29, 0xd6, 0x69, 0x2f, 0x1b, 0x70, 0x9c, 0xa0, 0x42, 0xb6, 0x5a, 0x8c, 0xe6, 0x18, 0x3d, + 0xe8, 0xc5, 0xa8, 0x5c, 0x7a, 0xda, 0xff, 0x2f, 0x97, 0xf0, 0xa0, 0xb6, 0x42, 0x42, 0x50, 0x00, + 0x45, 0x3f, 0xa8, 0x29, 0x63, 0x7d, 0x2d, 0x1b, 0x63, 0x7d, 0x23, 0xa8, 0x19, 0x69, 0x7c, 0xf4, + 0x5f, 0x84, 0xb9, 0x1c, 0x96, 0xe7, 0x24, 0x13, 0xc2, 0x18, 0x42, 0xac, 0x0b, 0xb2, 0x94, 0xac, + 0xf2, 0x9c, 0xd6, 0x4d, 0x41, 0x38, 0x29, 0x17, 0xed, 0x42, 0x71, 0x27, 0x88, 0x62, 0xb9, 0x5a, + 0x38, 0xe6, 0xc2, 0xe4, 0x6a, 0x10, 0xc5, 0x6c, 0xda, 0x57, 0xaf, 0x4d, 0x21, 0x11, 0xe6, 0x32, + 0xec, 0xff, 0x6a, 0x25, 0xb6, 0x20, 0x6f, 0x3b, 0xb1, 0xbb, 0x73, 0x79, 0x8f, 0xf8, 0x74, 0x1c, + 0x9a, 0x81, 0xd3, 0x7f, 0x25, 0x15, 0x38, 0xfd, 0x91, 0x41, 0x79, 0xd5, 0xf7, 0x28, 0x87, 0x39, + 0xc6, 0xc2, 0x08, 0xa2, 0xfe, 0xbc, 0x05, 0xe3, 0x86, 0x7a, 0x62, 0x22, 0xcc, 0x30, 0xfa, 0x5e, + 0x9f, 0xa4, 0x6a, 0x20, 0x36, 0x45, 0xda, 0xef, 0x5a, 0x30, 0x56, 0x75, 0xdc, 0xdd, 0xa0, 0x5e, + 0x47, 0x2f, 0x41, 0xb9, 0xd6, 0x11, 0xc9, 0x25, 0xfc, 0xfd, 0xd4, 0x9e, 0xd7, 0x92, 0x80, 0x63, + 0x45, 0x41, 0xfb, 0x70, 0xdd, 0x61, 0x91, 0x3b, 0x39, 0xe6, 0x0e, 0xb1, 0x3e, 0x7c, 0x85, 0x41, + 0xb0, 0xc0, 0xa0, 0x8f, 0xc1, 0x78, 0xcb, 0xd9, 0x97, 0x0f, 0xa7, 0xf7, 0x3f, 0xd7, 0x34, 0x0a, + 0x9b, 0x74, 0xf6, 0xbf, 0xb6, 0x60, 0xa6, 0xea, 0x44, 0x9e, 0xbb, 0xd0, 0x89, 0x77, 0xaa, 0x5e, + 0xbc, 0xdd, 0x71, 0x77, 0x49, 0xcc, 0x13, 0x2f, 0xa8, 0x96, 0x9d, 0x88, 0x0e, 0x25, 0xb5, 0x0c, + 0x53, 0x5a, 0xde, 0x14, 0x70, 0xac, 0x28, 0xd0, 0xdb, 0x30, 0xde, 0x76, 0xa2, 0xe8, 0x5e, 0x10, + 0xd6, 0x30, 0xa9, 0x67, 0x93, 0xf6, 0xb4, 0x49, 0xdc, 0x90, 0xc4, 0x98, 0xd4, 0xc5, 0x89, 0x96, + 0xe6, 0x8f, 0x4d, 0x61, 0xf6, 0xbf, 0xaa, 0xc0, 0x98, 0x38, 0x8e, 0x1b, 0x3a, 0x9d, 0x44, 0x2e, + 0x30, 0x73, 0x03, 0x17, 0x98, 0x11, 0x94, 0x5c, 0x96, 0x7c, 0x2f, 0x3c, 0x99, 0xeb, 0x99, 0x9c, + 0xdf, 0xf2, 0x7c, 0x7e, 0xad, 0x16, 0xff, 0x8f, 0x85, 0x28, 0xf4, 0x0d, 0x0b, 0x4e, 0xb9, 0x81, + 0xef, 0x13, 0x57, 0x4f, 0xb3, 0x85, 0x2c, 0x22, 0x32, 0x16, 0x93, 0x4c, 0xf5, 0xe6, 0x6f, 0x0a, + 0x81, 0xd3, 0xe2, 0xd1, 0xeb, 0x30, 0xc9, 0xdb, 0xec, 0x56, 0x62, 0xe7, 0x4b, 0x67, 0x4d, 0x9a, + 0x48, 0x9c, 0xa4, 0x45, 0x73, 0x7c, 0x07, 0x51, 0xe4, 0x27, 0x96, 0xf4, 0x49, 0x82, 0x91, 0x99, + 0x68, 0x50, 0xa0, 0x10, 0x50, 0x48, 0xea, 0x21, 0x89, 0x76, 0xc4, 0x71, 0x25, 0x9b, 0xe2, 0xc7, + 0x1e, 0x2e, 0x87, 0x01, 0xf7, 0x70, 0xc2, 0x7d, 0xb8, 0xa3, 0x5d, 0xb1, 0xc6, 0x29, 0x67, 0x61, + 0x15, 0xc4, 0x67, 0x1e, 0xb8, 0xd4, 0x99, 0x85, 0x62, 0xb4, 0xe3, 0x84, 0x35, 0xe6, 0x5a, 0xe4, + 0xf9, 0x46, 0xc0, 0x26, 0x05, 0x60, 0x0e, 0x47, 0x4b, 0x70, 0x3a, 0x95, 0xf3, 0x19, 0x31, 0xe7, + 0xa1, 0x5c, 0x9d, 0x11, 0xec, 0x4e, 0xa7, 0xb2, 0x45, 0x23, 0xdc, 0xf3, 0x84, 0xb9, 0xfe, 0x1d, + 0x3f, 0x62, 0xfd, 0xdb, 0x55, 0x41, 0x31, 0x13, 0xcc, 0xe2, 0xbf, 0x99, 0x49, 0x03, 0x0c, 0x15, + 0x01, 0xf3, 0xb5, 0x54, 0x04, 0xcc, 0x24, 0x53, 0xe0, 0x56, 0x36, 0x0a, 0x8c, 0x1e, 0xee, 0xf2, + 0x38, 0xc3, 0x57, 0xfe, 0xaf, 0x05, 0xf2, 0xbb, 0x2e, 0x3a, 0xee, 0x0e, 0xa1, 0x5d, 0x06, 0xbd, + 0x01, 0x53, 0x6a, 0x15, 0xb7, 0x18, 0x74, 0x7c, 0x1e, 0xb9, 0x92, 0xd7, 0xa7, 0x44, 0x38, 0x81, + 0xc5, 0x29, 0x6a, 0x34, 0x0f, 0x15, 0xda, 0x4e, 0xfc, 0x51, 0x3e, 0x7b, 0xa8, 0x95, 0xe2, 0xc2, + 0xc6, 0x8a, 0x78, 0x4a, 0xd3, 0xa0, 0x00, 0xa6, 0x9b, 0x4e, 0x14, 0x33, 0x0d, 0xe8, 0xa2, 0xee, + 0x21, 0x33, 0x88, 0x58, 0xca, 0xfb, 0x6a, 0x9a, 0x11, 0xee, 0xe5, 0x6d, 0x7f, 0xaf, 0x00, 0x93, + 0x09, 0xcb, 0x38, 0xe2, 0xb4, 0xf3, 0x12, 0x94, 0xe5, 0x4c, 0x20, 0x4c, 0xb9, 0xa2, 0x56, 0xd3, + 0x85, 0xa2, 0xa0, 0xd3, 0xe4, 0x36, 0x71, 0x42, 0x12, 0xb2, 0x6c, 0xda, 0xf4, 0x34, 0x59, 0xd5, + 0x28, 0x6c, 0xd2, 0x31, 0xa3, 0x1c, 0x37, 0xa3, 0xc5, 0xa6, 0x47, 0xfc, 0x98, 0xab, 0x99, 0x8d, + 0x51, 0xde, 0x5a, 0xdd, 0x34, 0x99, 0x6a, 0xa3, 0x9c, 0x42, 0xe0, 0xb4, 0x78, 0xf4, 0x25, 0x0b, + 0x26, 0x9d, 0x7b, 0x91, 0xae, 0x10, 0x23, 0x62, 0x5d, 0x8e, 0x39, 0x49, 0x25, 0x8a, 0xce, 0x54, + 0xa7, 0xa9, 0x79, 0x4f, 0x80, 0x70, 0x52, 0x28, 0xfa, 0xa6, 0x05, 0x88, 0xec, 0x13, 0x57, 0x46, + 0xe3, 0x08, 0x5d, 0x4a, 0x59, 0x2c, 0x76, 0x2e, 0xf7, 0xf0, 0xe5, 0x56, 0xbd, 0x17, 0x8e, 0xfb, + 0xe8, 0x60, 0xff, 0xb3, 0xbc, 0x1a, 0x50, 0x3a, 0x00, 0xcc, 0x31, 0xe2, 0xa0, 0xad, 0x87, 0x8f, + 0x83, 0xd6, 0x47, 0x94, 0x3d, 0xb1, 0xd0, 0xc9, 0xa0, 0xe1, 0xdc, 0x63, 0x0a, 0x1a, 0xfe, 0xa2, + 0xa5, 0x4e, 0xb6, 0xb9, 0x1b, 0xff, 0x56, 0xb6, 0xc1, 0x67, 0x73, 0xfc, 0x80, 0x3c, 0x65, 0xdd, + 0x93, 0xa7, 0xe6, 0xd4, 0x9a, 0x1a, 0x64, 0x23, 0x59, 0xc3, 0xff, 0x98, 0x87, 0x71, 0x63, 0x26, + 0xed, 0xeb, 0x16, 0x59, 0x4f, 0x98, 0x5b, 0x94, 0x1b, 0xc1, 0x2d, 0xfa, 0x45, 0xa8, 0xb8, 0xd2, + 0xca, 0x67, 0x53, 0x8e, 0x28, 0x3d, 0x77, 0x68, 0x43, 0xaf, 0x40, 0x58, 0xcb, 0x44, 0xcb, 0x30, + 0x6d, 0xb0, 0x11, 0x33, 0x44, 0x81, 0xcd, 0x10, 0x6a, 0x83, 0x78, 0x21, 0x4d, 0x80, 0x7b, 0x9f, + 0x41, 0xaf, 0xd0, 0x95, 0x95, 0x27, 0xde, 0x4b, 0x86, 0x88, 0x32, 0x77, 0x7d, 0x61, 0x63, 0x45, + 0x82, 0xb1, 0x49, 0x63, 0x7f, 0xcf, 0x52, 0x1f, 0xf7, 0x11, 0x64, 0x56, 0xdd, 0x49, 0x66, 0x56, + 0x5d, 0xce, 0xa4, 0x99, 0x07, 0xa4, 0x54, 0xdd, 0x80, 0xb1, 0xc5, 0xa0, 0xd5, 0x72, 0xfc, 0x1a, + 0xfa, 0x11, 0x18, 0x73, 0xf9, 0x4f, 0xb1, 0x55, 0xc1, 0xce, 0xa7, 0x04, 0x16, 0x4b, 0x1c, 0x7a, + 0x0e, 0x0a, 0x4e, 0xd8, 0x90, 0xdb, 0x13, 0xec, 0x48, 0x7f, 0x21, 0x6c, 0x44, 0x98, 0x41, 0xed, + 0x77, 0xf2, 0x00, 0x8b, 0x41, 0xab, 0xed, 0x84, 0xa4, 0xb6, 0x15, 0xb0, 0x72, 0x08, 0x27, 0x7a, + 0xae, 0xa3, 0x17, 0x4b, 0x4f, 0xf2, 0xd9, 0x8e, 0xb1, 0xbf, 0x9f, 0x7f, 0xd4, 0xfb, 0xfb, 0x5f, + 0xb5, 0x00, 0xd1, 0x2f, 0x12, 0xf8, 0xc4, 0x8f, 0xf5, 0x71, 0xe5, 0x3c, 0x54, 0x5c, 0x09, 0x15, + 0x5e, 0x8b, 0x1e, 0x7f, 0x12, 0x81, 0x35, 0xcd, 0x10, 0xcb, 0xcf, 0x17, 0xa4, 0x71, 0xcc, 0x27, + 0xa3, 0xe0, 0x98, 0x49, 0x15, 0xb6, 0xd2, 0xfe, 0xbd, 0x1c, 0x3c, 0xc5, 0xe7, 0xbb, 0x35, 0xc7, + 0x77, 0x1a, 0xa4, 0x45, 0xb5, 0x1a, 0xf6, 0x00, 0xda, 0xa5, 0xeb, 0x1e, 0x4f, 0x46, 0xb5, 0x1d, + 0x77, 0x60, 0xf0, 0x0e, 0xcd, 0xbb, 0xf0, 0x8a, 0xef, 0xc5, 0x98, 0x31, 0x47, 0x11, 0x94, 0x65, + 0x71, 0x3b, 0x61, 0xe8, 0x32, 0x12, 0xa4, 0xc6, 0xbc, 0x98, 0x94, 0x08, 0x56, 0x82, 0xa8, 0x57, + 0xd8, 0x0c, 0xdc, 0x5d, 0x4c, 0xda, 0x01, 0x33, 0x6a, 0x46, 0x50, 0xd1, 0xaa, 0x80, 0x63, 0x45, + 0x61, 0xff, 0x9e, 0x05, 0x69, 0x73, 0xcf, 0xb6, 0x11, 0x78, 0x5e, 0x7b, 0x7a, 0x1b, 0x21, 0x99, + 0xb6, 0x3e, 0x42, 0x7a, 0xfe, 0xcf, 0xc0, 0xb8, 0x13, 0xd3, 0x19, 0x9a, 0xaf, 0x69, 0xf3, 0x0f, + 0xb7, 0x6d, 0xbd, 0x16, 0xd4, 0xbc, 0xba, 0xc7, 0xd6, 0xb2, 0x26, 0x3b, 0xfb, 0x7f, 0x17, 0x60, + 0xba, 0x27, 0x52, 0x19, 0xbd, 0x06, 0x13, 0xae, 0xe8, 0x1e, 0x6d, 0x4c, 0xea, 0xe2, 0x65, 0x8c, + 0x48, 0x17, 0x8d, 0xc3, 0x09, 0xca, 0x21, 0x3a, 0xe8, 0x0a, 0x9c, 0x09, 0xe9, 0x2a, 0xba, 0x43, + 0x16, 0xea, 0x31, 0x09, 0x37, 0x89, 0x1b, 0xf8, 0x35, 0x5e, 0x7f, 0x21, 0x5f, 0x7d, 0xfa, 0xf0, + 0x60, 0xf6, 0x0c, 0xee, 0x45, 0xe3, 0x7e, 0xcf, 0xa0, 0x36, 0x4c, 0x36, 0x4d, 0x07, 0x4b, 0x78, + 0xd7, 0x0f, 0xe5, 0x9b, 0xa9, 0x09, 0x38, 0x01, 0xc6, 0x49, 0x01, 0x49, 0x2f, 0xad, 0xf8, 0x98, + 0xbc, 0xb4, 0x5f, 0xd2, 0x5e, 0x1a, 0x3f, 0x5f, 0xfd, 0x54, 0xc6, 0x91, 0xea, 0x27, 0xed, 0xa6, + 0xbd, 0x09, 0x65, 0x19, 0x79, 0x32, 0x54, 0xc4, 0x86, 0xc9, 0x67, 0x80, 0x45, 0xbb, 0x9f, 0x83, + 0x3e, 0x1e, 0x3e, 0x1d, 0x67, 0x7a, 0x3a, 0x4d, 0x8c, 0xb3, 0xd1, 0xa6, 0x54, 0xb4, 0xcf, 0xa3, + 0x6e, 0xf8, 0xc4, 0xf1, 0xc9, 0xac, 0x57, 0x28, 0x3a, 0x10, 0x47, 0x85, 0x80, 0xa8, 0x60, 0x9c, + 0x4b, 0x00, 0xda, 0x0b, 0x12, 0x01, 0xa7, 0xea, 0x58, 0x4f, 0x3b, 0x4b, 0xd8, 0xa0, 0xa2, 0x0b, + 0x56, 0xcf, 0x8f, 0x62, 0xa7, 0xd9, 0xbc, 0xea, 0xf9, 0xb1, 0xd8, 0x79, 0x53, 0x33, 0xe4, 0x8a, + 0x46, 0x61, 0x93, 0xee, 0xfc, 0xc7, 0x8d, 0xef, 0x32, 0xca, 0xf7, 0xdc, 0x81, 0x67, 0x96, 0xbd, + 0x58, 0x85, 0x49, 0xab, 0x7e, 0x44, 0x9d, 0x1c, 0x15, 0xf6, 0x6f, 0x0d, 0x0c, 0xfb, 0x37, 0xc2, + 0x94, 0x73, 0xc9, 0xa8, 0xea, 0x74, 0x98, 0xb2, 0xfd, 0x1a, 0x9c, 0x5d, 0xf6, 0xe2, 0x2b, 0x5e, + 0x93, 0x8c, 0x28, 0xc4, 0xfe, 0x52, 0x11, 0x26, 0xcc, 0xb4, 0x94, 0x51, 0x32, 0x17, 0xbe, 0x4e, + 0xfd, 0x18, 0xf1, 0x76, 0x9e, 0x3a, 0x63, 0xb9, 0x7d, 0xec, 0x1c, 0x99, 0xfe, 0x2d, 0x66, 0xb8, + 0x32, 0x5a, 0x26, 0x36, 0x15, 0x40, 0xf7, 0xa0, 0x58, 0x67, 0x61, 0xb4, 0xf9, 0x2c, 0x4e, 0x8e, + 0xfb, 0xb5, 0xa8, 0x1e, 0x66, 0x3c, 0x10, 0x97, 0xcb, 0xa3, 0x33, 0x64, 0x98, 0xcc, 0xcd, 0x50, + 0x86, 0x4a, 0x65, 0x65, 0x28, 0x8a, 0x41, 0xa6, 0xbe, 0xf8, 0x10, 0xa6, 0x3e, 0x61, 0x78, 0x4b, + 0x8f, 0xc9, 0xf0, 0xb2, 0x90, 0xe8, 0x78, 0x87, 0xf9, 0x6f, 0x22, 0x20, 0x76, 0x8c, 0x35, 0x82, + 0x11, 0x12, 0x9d, 0x40, 0xe3, 0x34, 0xbd, 0xfd, 0xd5, 0x1c, 0x4c, 0x2d, 0xfb, 0x9d, 0x8d, 0xe5, + 0x8d, 0xce, 0x76, 0xd3, 0x73, 0xaf, 0x93, 0x2e, 0xb5, 0x6f, 0xbb, 0xa4, 0xbb, 0xb2, 0x24, 0xba, + 0xa1, 0x6a, 0xf8, 0xeb, 0x14, 0x88, 0x39, 0x8e, 0x8e, 0xe8, 0xba, 0xe7, 0x37, 0x48, 0xd8, 0x0e, + 0x3d, 0xb1, 0x29, 0x67, 0x8c, 0xe8, 0x2b, 0x1a, 0x85, 0x4d, 0x3a, 0xca, 0x3b, 0xb8, 0xe7, 0x93, + 0x30, 0xed, 0x0d, 0xae, 0x53, 0x20, 0xe6, 0x38, 0x4a, 0x14, 0x87, 0x9d, 0x28, 0x16, 0x5f, 0x54, + 0x11, 0x6d, 0x51, 0x20, 0xe6, 0x38, 0x3a, 0x5c, 0xa2, 0xce, 0x36, 0x3b, 0xdd, 0x4e, 0x85, 0xb0, + 0x6e, 0x72, 0x30, 0x96, 0x78, 0x4a, 0xba, 0x4b, 0xba, 0x4b, 0x74, 0x5d, 0x96, 0x0a, 0x32, 0xbf, + 0xce, 0xc1, 0x58, 0xe2, 0x59, 0xd1, 0x8c, 0x64, 0x73, 0xfc, 0xc0, 0x15, 0xcd, 0x48, 0xaa, 0x3f, + 0x60, 0x85, 0xf7, 0x6d, 0x0b, 0x26, 0xcc, 0x98, 0x14, 0xd4, 0x48, 0x39, 0x8a, 0xeb, 0x3d, 0x05, + 0x90, 0x7e, 0xb2, 0x5f, 0x4d, 0xee, 0x86, 0x17, 0x07, 0xed, 0xe8, 0x65, 0xe2, 0x37, 0x3c, 0x9f, + 0xb0, 0x93, 0x4b, 0x1e, 0xcb, 0x92, 0x08, 0x78, 0x59, 0x0c, 0x6a, 0xe4, 0x21, 0x3c, 0x4d, 0xfb, + 0x36, 0x4c, 0xf7, 0x64, 0x16, 0x0c, 0x31, 0x3f, 0x1f, 0x99, 0xd7, 0x65, 0x63, 0x18, 0xa7, 0x8c, + 0xd7, 0xdb, 0x3c, 0xe8, 0x64, 0x11, 0xa6, 0xb9, 0x0f, 0x41, 0x25, 0x6d, 0xba, 0x3b, 0xa4, 0xa5, + 0xb2, 0x45, 0xd8, 0x0e, 0xf0, 0xad, 0x34, 0x12, 0xf7, 0xd2, 0xdb, 0x5f, 0xb3, 0x60, 0x32, 0x91, + 0xec, 0x91, 0x91, 0x27, 0xc1, 0x46, 0x5a, 0xc0, 0x42, 0xa4, 0x58, 0x94, 0x68, 0x9e, 0xcd, 0x48, + 0x7a, 0xa4, 0x69, 0x14, 0x36, 0xe9, 0xec, 0x77, 0x73, 0x50, 0x96, 0xa7, 0xd6, 0x43, 0xa8, 0xf2, + 0x15, 0x0b, 0x26, 0xd5, 0xae, 0x3b, 0xdb, 0xce, 0xe1, 0x9d, 0xf1, 0xc6, 0xf1, 0xcf, 0xcd, 0x55, + 0x0c, 0x9f, 0x5f, 0x0f, 0xb4, 0x5b, 0x8b, 0x4d, 0x61, 0x38, 0x29, 0x1b, 0xdd, 0x02, 0x88, 0xba, + 0x51, 0x4c, 0x5a, 0xc6, 0xc6, 0x92, 0x6d, 0x8c, 0xb8, 0x39, 0x37, 0x08, 0x09, 0x1d, 0x5f, 0x37, + 0x82, 0x1a, 0xd9, 0x54, 0x94, 0xda, 0x0f, 0xd1, 0x30, 0x6c, 0x70, 0xb2, 0xff, 0x61, 0x0e, 0x4e, + 0xa7, 0x55, 0x42, 0x9f, 0x82, 0x09, 0x29, 0xdd, 0x28, 0x4a, 0x2e, 0x8f, 0xea, 0x27, 0xb0, 0x81, + 0xbb, 0x7f, 0x30, 0x3b, 0xdb, 0x5b, 0xdf, 0x7d, 0xce, 0x24, 0xc1, 0x09, 0x66, 0xfc, 0xe8, 0x43, + 0x9c, 0xd1, 0x55, 0xbb, 0x0b, 0xed, 0xb6, 0x38, 0xbf, 0x30, 0x8e, 0x3e, 0x4c, 0x2c, 0x4e, 0x51, + 0xa3, 0x0d, 0x38, 0x6b, 0x40, 0x6e, 0x10, 0xaf, 0xb1, 0xb3, 0x1d, 0x84, 0x72, 0x79, 0xf2, 0x9c, + 0x8e, 0x7e, 0xe9, 0xa5, 0xc1, 0x7d, 0x9f, 0xa4, 0x53, 0xa6, 0xeb, 0xb4, 0x1d, 0xd7, 0x8b, 0xbb, + 0x62, 0xa7, 0x4c, 0xd9, 0xa6, 0x45, 0x01, 0xc7, 0x8a, 0xc2, 0x5e, 0x83, 0xc2, 0x90, 0x3d, 0x68, + 0x28, 0xb7, 0xf8, 0x4d, 0x28, 0x53, 0x76, 0xd2, 0x47, 0xca, 0x82, 0x65, 0x00, 0x65, 0x59, 0x57, + 0x14, 0xd9, 0x90, 0xf7, 0x1c, 0x79, 0xba, 0xa4, 0x5e, 0x6b, 0x25, 0x8a, 0x3a, 0x6c, 0xa5, 0x49, + 0x91, 0xe8, 0x05, 0xc8, 0x93, 0xfd, 0x76, 0xfa, 0x18, 0xe9, 0xf2, 0x7e, 0xdb, 0x0b, 0x49, 0x44, + 0x89, 0xc8, 0x7e, 0x1b, 0x9d, 0x87, 0x9c, 0x57, 0x13, 0x93, 0x14, 0x08, 0x9a, 0xdc, 0xca, 0x12, + 0xce, 0x79, 0x35, 0x7b, 0x1f, 0x2a, 0xaa, 0x90, 0x29, 0xda, 0x95, 0xb6, 0xdb, 0xca, 0x22, 0xcc, + 0x44, 0xf2, 0x1d, 0x60, 0xb5, 0x3b, 0x00, 0x3a, 0xb5, 0x26, 0x2b, 0xfb, 0x72, 0x11, 0x0a, 0x6e, + 0x20, 0x32, 0xf2, 0xca, 0x9a, 0x0d, 0x33, 0xda, 0x0c, 0x63, 0xdf, 0x86, 0xa9, 0xeb, 0x7e, 0x70, + 0x8f, 0x95, 0xf3, 0xbb, 0xe2, 0x91, 0x66, 0x8d, 0x32, 0xae, 0xd3, 0x1f, 0x69, 0x17, 0x81, 0x61, + 0x31, 0xc7, 0xa9, 0x6a, 0x9f, 0xb9, 0x41, 0xd5, 0x3e, 0xed, 0xcf, 0x5b, 0x70, 0x5a, 0xe5, 0x7c, + 0x48, 0x6b, 0xfc, 0x1a, 0x4c, 0x6c, 0x77, 0xbc, 0x66, 0x4d, 0xfc, 0x4f, 0xaf, 0xf5, 0xab, 0x06, + 0x0e, 0x27, 0x28, 0xe9, 0xca, 0x64, 0xdb, 0xf3, 0x9d, 0xb0, 0xbb, 0xa1, 0xcd, 0xbf, 0xb2, 0x08, + 0x55, 0x85, 0xc1, 0x06, 0x95, 0xfd, 0xc5, 0x1c, 0x4c, 0x26, 0x32, 0xe0, 0x51, 0x13, 0xca, 0xa4, + 0xc9, 0x76, 0xa0, 0xe4, 0x47, 0x3d, 0x6e, 0x1d, 0x1b, 0xd5, 0x11, 0x2f, 0x0b, 0xbe, 0x58, 0x49, + 0x78, 0x22, 0x8e, 0x59, 0xec, 0xdf, 0xcf, 0xc3, 0x0c, 0xdf, 0x78, 0xab, 0xa9, 0x78, 0x86, 0x35, + 0xe9, 0x9d, 0xfc, 0x75, 0x5d, 0x6d, 0x82, 0x37, 0xc7, 0xf6, 0x71, 0x2b, 0xb1, 0xf5, 0x17, 0x34, + 0xd4, 0x49, 0xfb, 0xdf, 0x4e, 0x9d, 0xb4, 0xe7, 0xb2, 0x48, 0x88, 0x18, 0xa8, 0xd1, 0x0f, 0xd6, + 0xd1, 0xfb, 0xdf, 0xcb, 0xc1, 0xa9, 0x54, 0x99, 0x3b, 0xf4, 0x4e, 0xb2, 0x0c, 0x91, 0x95, 0xc5, + 0xf6, 0xcc, 0x03, 0x8b, 0xad, 0x8d, 0x56, 0x8c, 0xe8, 0x71, 0x75, 0xf8, 0x3f, 0xcc, 0xc1, 0x54, + 0xb2, 0x3e, 0xdf, 0x13, 0xd8, 0x52, 0x1f, 0x85, 0x0a, 0xab, 0x7a, 0xc5, 0xca, 0xc5, 0xf3, 0x5d, + 0x20, 0x96, 0xe7, 0xbe, 0x26, 0x81, 0x58, 0xe3, 0x9f, 0x88, 0x1a, 0x4f, 0xf6, 0xdf, 0xb7, 0xe0, + 0x1c, 0x7f, 0xcb, 0x74, 0x3f, 0xfc, 0x1b, 0xfd, 0x5a, 0xf7, 0xd3, 0xd9, 0x2a, 0x98, 0xaa, 0x92, + 0x72, 0x54, 0xfb, 0xb2, 0x32, 0xd5, 0x42, 0xdb, 0x64, 0x57, 0x78, 0x02, 0x95, 0x1d, 0xa9, 0x33, + 0xd8, 0x7f, 0x98, 0x07, 0x5d, 0x99, 0x1b, 0x79, 0x22, 0x6d, 0x22, 0x93, 0x6a, 0x31, 0x9b, 0x5d, + 0xdf, 0xd5, 0x35, 0xc0, 0xcb, 0xa9, 0xac, 0x89, 0x5f, 0xb5, 0x60, 0xdc, 0xf3, 0xbd, 0xd8, 0x73, + 0x98, 0xd3, 0x99, 0x4d, 0xe9, 0x64, 0x25, 0x6e, 0x85, 0x73, 0x0e, 0x42, 0x73, 0xeb, 0x50, 0x09, + 0xc3, 0xa6, 0x64, 0xf4, 0x39, 0x11, 0x0c, 0x97, 0xcf, 0x2c, 0xe1, 0xa7, 0x9c, 0x8a, 0x80, 0x6b, + 0x43, 0x31, 0x24, 0x71, 0x28, 0x53, 0xad, 0xae, 0x1f, 0x37, 0xc2, 0x39, 0x0e, 0xbb, 0x9b, 0x71, + 0xe8, 0xc4, 0xa4, 0x61, 0x2c, 0xda, 0x19, 0x18, 0x73, 0x41, 0x76, 0x04, 0xa8, 0xb7, 0x2d, 0x46, + 0x0c, 0x34, 0x9a, 0x87, 0x8a, 0xd3, 0x89, 0x83, 0x16, 0x6d, 0x26, 0xb1, 0xbb, 0xa9, 0x43, 0xa9, + 0x24, 0x02, 0x6b, 0x1a, 0xfb, 0x9d, 0x22, 0xa4, 0xf2, 0x18, 0xd0, 0xbe, 0x59, 0x55, 0xde, 0xca, + 0xb6, 0xaa, 0xbc, 0x52, 0xa6, 0x5f, 0x65, 0x79, 0xd4, 0x80, 0x62, 0x7b, 0xc7, 0x89, 0xa4, 0x4f, + 0xf9, 0xa6, 0x6c, 0xa6, 0x0d, 0x0a, 0xbc, 0x7f, 0x30, 0xfb, 0x53, 0xc3, 0xed, 0x51, 0xd0, 0xbe, + 0x3a, 0xcf, 0xf3, 0x85, 0xb5, 0x68, 0xc6, 0x03, 0x73, 0xfe, 0xe6, 0x2e, 0x45, 0xfe, 0x88, 0xf3, + 0xb0, 0x2f, 0x88, 0xc2, 0x76, 0x98, 0x44, 0x9d, 0x66, 0x2c, 0x7a, 0xc3, 0x9b, 0x19, 0x8e, 0x32, + 0xce, 0x58, 0x67, 0xe0, 0xf1, 0xff, 0xd8, 0x10, 0x8a, 0x3e, 0x05, 0x95, 0x28, 0x76, 0xc2, 0xf8, + 0x21, 0x73, 0x66, 0x54, 0xa3, 0x6f, 0x4a, 0x26, 0x58, 0xf3, 0x43, 0x6f, 0xb1, 0xe2, 0x59, 0x5e, + 0xb4, 0xf3, 0x90, 0x31, 0xac, 0xb2, 0xd0, 0x96, 0xe0, 0x80, 0x0d, 0x6e, 0xd4, 0x65, 0x67, 0x7d, + 0x9b, 0x07, 0x6e, 0x94, 0xd9, 0x9a, 0x4c, 0x99, 0x42, 0xac, 0x30, 0xd8, 0xa0, 0xb2, 0x7f, 0x01, + 0xce, 0xa4, 0xaf, 0xa1, 0x11, 0xdb, 0x96, 0x8d, 0x30, 0xe8, 0xb4, 0xd3, 0x6b, 0x12, 0x76, 0x4d, + 0x09, 0xe6, 0x38, 0xba, 0x26, 0xd9, 0xf5, 0xfc, 0x5a, 0x7a, 0x4d, 0x72, 0xdd, 0xf3, 0x6b, 0x98, + 0x61, 0x86, 0x28, 0xb7, 0xff, 0xcf, 0x2d, 0xb8, 0x78, 0xd4, 0x6d, 0x39, 0xe8, 0x39, 0x28, 0xdc, + 0x73, 0x42, 0x59, 0x8c, 0x8f, 0xd9, 0x8e, 0xdb, 0x4e, 0xe8, 0x63, 0x06, 0x45, 0x5d, 0x28, 0xf1, + 0x1c, 0x45, 0xe1, 0xc0, 0xbe, 0x99, 0xed, 0xdd, 0x3d, 0xd7, 0x89, 0xe1, 0x41, 0xf3, 0xfc, 0x48, + 0x2c, 0x04, 0xda, 0xef, 0x5b, 0x80, 0xd6, 0xf7, 0x48, 0x18, 0x7a, 0x35, 0x23, 0xab, 0x12, 0xbd, + 0x0a, 0x13, 0x77, 0x36, 0xd7, 0x6f, 0x6c, 0x04, 0x9e, 0xcf, 0x72, 0xac, 0x8d, 0xbc, 0x94, 0x6b, + 0x06, 0x1c, 0x27, 0xa8, 0xd0, 0x22, 0x4c, 0xdf, 0xb9, 0x4b, 0xd7, 0x51, 0x97, 0xf7, 0xdb, 0x21, + 0x89, 0x22, 0xe5, 0x93, 0x8b, 0x9d, 0xb3, 0x6b, 0x6f, 0xa6, 0x90, 0xb8, 0x97, 0x1e, 0xad, 0xc3, + 0xb9, 0x16, 0xf7, 0xc0, 0xd9, 0xf2, 0x31, 0xe2, 0xee, 0x78, 0x28, 0x0b, 0x2f, 0x3c, 0x73, 0x78, + 0x30, 0x7b, 0x6e, 0xad, 0x1f, 0x01, 0xee, 0xff, 0x9c, 0xfd, 0x9d, 0x1c, 0x8c, 0x1b, 0x37, 0x4e, + 0x0d, 0xb1, 0x50, 0x4e, 0x5d, 0x92, 0x95, 0x1b, 0xf2, 0x92, 0xac, 0x17, 0xa1, 0xdc, 0x0e, 0x9a, + 0x9e, 0xeb, 0xa9, 0x2a, 0x11, 0xac, 0x98, 0xd9, 0x86, 0x80, 0x61, 0x85, 0x45, 0xf7, 0xa0, 0xa2, + 0x6e, 0x61, 0x11, 0xc9, 0x7d, 0x59, 0x6d, 0x15, 0xa8, 0xc1, 0xab, 0x6f, 0x57, 0xd1, 0xb2, 0x90, + 0x0d, 0x25, 0xd6, 0xf3, 0x65, 0x48, 0x13, 0xcb, 0xba, 0x60, 0x43, 0x22, 0xc2, 0x02, 0x63, 0xff, + 0xf2, 0x18, 0x9c, 0xed, 0x57, 0x80, 0x0b, 0xfd, 0x1c, 0x94, 0xb8, 0x8e, 0xd9, 0xd4, 0x78, 0xec, + 0x27, 0x63, 0x99, 0x31, 0x14, 0x6a, 0xb1, 0xdf, 0x58, 0xc8, 0x14, 0xd2, 0x9b, 0xce, 0xb6, 0x70, + 0x23, 0x4e, 0x46, 0xfa, 0xaa, 0xa3, 0xa5, 0xaf, 0x3a, 0x5c, 0x7a, 0xd3, 0xd9, 0x46, 0xfb, 0x50, + 0x6c, 0x78, 0x31, 0x71, 0x84, 0x33, 0x7d, 0xfb, 0x44, 0x84, 0x13, 0x87, 0x47, 0xce, 0xb3, 0x9f, + 0x98, 0x0b, 0x44, 0xdf, 0xb2, 0xe0, 0xd4, 0x76, 0x32, 0x89, 0x45, 0xcc, 0x2a, 0xce, 0x09, 0x14, + 0x59, 0x4b, 0x0a, 0xaa, 0x9e, 0x39, 0x3c, 0x98, 0x3d, 0x95, 0x02, 0xe2, 0xb4, 0x3a, 0xe8, 0x97, + 0x2c, 0x18, 0xab, 0x7b, 0x4d, 0xa3, 0x82, 0xd0, 0x09, 0x7c, 0x9c, 0x2b, 0x4c, 0x80, 0x9e, 0x79, + 0xf9, 0xff, 0x08, 0x4b, 0xc9, 0x83, 0x8e, 0xf3, 0x4a, 0xc7, 0x3d, 0xce, 0x1b, 0x7b, 0x4c, 0xcb, + 0xa7, 0xbf, 0x99, 0x83, 0x17, 0x86, 0xf8, 0x46, 0x66, 0x52, 0x84, 0x75, 0x44, 0x52, 0xc4, 0x45, + 0x28, 0x84, 0xa4, 0x1d, 0xa4, 0xe7, 0x3b, 0x16, 0x39, 0xc4, 0x30, 0xe8, 0x79, 0xc8, 0x3b, 0x6d, + 0x4f, 0x4c, 0x77, 0xea, 0xb4, 0x7f, 0x61, 0x63, 0x05, 0x53, 0x38, 0xfd, 0xd2, 0x95, 0x6d, 0x99, + 0x5a, 0x95, 0x4d, 0xd5, 0xde, 0x41, 0x99, 0x5a, 0x7c, 0x41, 0xa3, 0xb0, 0x58, 0xcb, 0xb5, 0xd7, + 0xe1, 0xfc, 0xe0, 0x1e, 0x82, 0x5e, 0x81, 0xf1, 0xed, 0xd0, 0xf1, 0xdd, 0x9d, 0x35, 0x27, 0x76, + 0xe5, 0x99, 0x3b, 0x8b, 0xdd, 0xac, 0x6a, 0x30, 0x36, 0x69, 0xec, 0xdf, 0xcf, 0xf5, 0xe7, 0xc8, + 0x8d, 0xc0, 0x28, 0x2d, 0x2c, 0xda, 0x2f, 0x37, 0xa0, 0xfd, 0xee, 0x42, 0x39, 0x66, 0x91, 0xf8, + 0xa4, 0x2e, 0x2c, 0x49, 0x66, 0xc9, 0x64, 0x6c, 0xae, 0xd9, 0x12, 0xcc, 0xb1, 0x12, 0x43, 0x4d, + 0x7e, 0x53, 0x17, 0x1f, 0x12, 0x26, 0x3f, 0xb5, 0x8f, 0xb6, 0x04, 0xa7, 0x8d, 0x5a, 0x8a, 0x3c, + 0x10, 0x99, 0x1f, 0xa3, 0xaa, 0xec, 0x9c, 0x8d, 0x14, 0x1e, 0xf7, 0x3c, 0x61, 0x7f, 0x3b, 0x07, + 0xcf, 0x0c, 0xb4, 0x6c, 0xfa, 0xac, 0xd7, 0x7a, 0xc0, 0x59, 0xef, 0xb1, 0x3b, 0xa8, 0xd9, 0xc0, + 0x85, 0x47, 0xd3, 0xc0, 0x2f, 0x41, 0xd9, 0xf3, 0x23, 0xe2, 0x76, 0x42, 0xde, 0x68, 0x46, 0x58, + 0xde, 0x8a, 0x80, 0x63, 0x45, 0x61, 0xff, 0xd1, 0xe0, 0xae, 0x46, 0x67, 0xb9, 0x1f, 0xda, 0x56, + 0x7a, 0x1d, 0x26, 0x9d, 0x76, 0x9b, 0xd3, 0xb1, 0x73, 0xb5, 0x54, 0xbe, 0xdd, 0x82, 0x89, 0xc4, + 0x49, 0x5a, 0xa3, 0x0f, 0x97, 0x06, 0xf5, 0x61, 0xfb, 0x4f, 0x2d, 0xa8, 0x60, 0x52, 0xe7, 0x35, + 0x38, 0xd1, 0x1d, 0xd1, 0x44, 0x56, 0x16, 0xc5, 0x21, 0xd8, 0x5d, 0xae, 0x1e, 0x2b, 0x9a, 0xd0, + 0xaf, 0xb1, 0x7b, 0xeb, 0x82, 0xe6, 0x46, 0xaa, 0x0b, 0xaa, 0x2a, 0x43, 0xe6, 0x07, 0x57, 0x86, + 0xb4, 0xbf, 0x5f, 0xa2, 0xaf, 0xd7, 0x0e, 0x16, 0x43, 0x52, 0x8b, 0xe8, 0xf7, 0xed, 0x84, 0x4d, + 0xd1, 0x49, 0xd4, 0xf7, 0xbd, 0x89, 0x57, 0x31, 0x85, 0x27, 0x36, 0x01, 0x72, 0x23, 0x65, 0x1b, + 0xe5, 0x8f, 0xcc, 0x36, 0x7a, 0x1d, 0x26, 0xa3, 0x68, 0x67, 0x23, 0xf4, 0xf6, 0x9c, 0x98, 0x2e, + 0x2d, 0x44, 0x58, 0x86, 0xce, 0x10, 0xd8, 0xbc, 0xaa, 0x91, 0x38, 0x49, 0x8b, 0x96, 0x61, 0x5a, + 0xe7, 0xfc, 0x90, 0x30, 0x66, 0x51, 0x18, 0xbc, 0x27, 0xa8, 0x00, 0x7d, 0x9d, 0x25, 0x24, 0x08, + 0x70, 0xef, 0x33, 0xd4, 0x62, 0x25, 0x80, 0x54, 0x91, 0x52, 0xd2, 0x62, 0x25, 0xf8, 0x50, 0x5d, + 0x7a, 0x9e, 0x40, 0x6b, 0x70, 0x86, 0x77, 0x0c, 0x76, 0xa7, 0xa2, 0x7a, 0x23, 0x1e, 0x35, 0xf3, + 0xac, 0x60, 0x74, 0x66, 0xb9, 0x97, 0x04, 0xf7, 0x7b, 0x8e, 0xae, 0x1b, 0x14, 0x78, 0x65, 0x49, + 0xac, 0x5f, 0xd5, 0xba, 0x41, 0xb1, 0x59, 0xa9, 0x61, 0x93, 0x0e, 0x7d, 0x12, 0x9e, 0xd6, 0x7f, + 0x79, 0xbc, 0x1b, 0xdf, 0xd4, 0x59, 0x12, 0xe9, 0x94, 0xaa, 0x0e, 0xe1, 0x72, 0x5f, 0xb2, 0x1a, + 0x1e, 0xf4, 0x3c, 0xda, 0x86, 0xf3, 0x0a, 0x75, 0x99, 0x2e, 0xd2, 0xda, 0xa1, 0x17, 0x91, 0xaa, + 0x13, 0x91, 0x9b, 0x61, 0x93, 0x25, 0x60, 0x56, 0x74, 0x41, 0xf5, 0x65, 0x2f, 0xbe, 0xda, 0x8f, + 0x12, 0xaf, 0xe2, 0x07, 0x70, 0x41, 0xf3, 0x50, 0x21, 0xbe, 0xb3, 0xdd, 0x24, 0xeb, 0x8b, 0x2b, + 0x2c, 0x2d, 0xd3, 0xd8, 0x43, 0xba, 0x2c, 0x11, 0x58, 0xd3, 0xa8, 0x93, 0xc0, 0x89, 0x81, 0xf7, + 0xfe, 0x6d, 0xc0, 0xd9, 0x86, 0xdb, 0xa6, 0x7e, 0x80, 0xe7, 0x92, 0x05, 0xd7, 0xa5, 0x0b, 0x7d, + 0xfa, 0x61, 0x78, 0x5d, 0x54, 0x75, 0xcc, 0xbd, 0xbc, 0xb8, 0xd1, 0x43, 0x83, 0xfb, 0x3e, 0x49, + 0xc7, 0x58, 0x3b, 0x0c, 0xf6, 0xbb, 0x33, 0x67, 0x92, 0x63, 0x6c, 0x83, 0x02, 0x31, 0xc7, 0xd9, + 0x7f, 0x62, 0xc1, 0xa4, 0x1a, 0x63, 0x8f, 0x20, 0xd2, 0xa7, 0x99, 0x8c, 0xf4, 0x59, 0x3e, 0xbe, + 0x95, 0x62, 0x9a, 0x0f, 0x38, 0x2e, 0xfe, 0x5d, 0x00, 0xd0, 0x96, 0x4c, 0x4d, 0x22, 0xd6, 0xc0, + 0x49, 0xe4, 0x89, 0xb5, 0x22, 0xfd, 0xf2, 0xa6, 0x8a, 0x8f, 0x37, 0x6f, 0x6a, 0x13, 0xce, 0xc9, + 0x29, 0x9e, 0x6f, 0xa3, 0x5c, 0x0d, 0x22, 0x65, 0x94, 0xca, 0xd5, 0xe7, 0x05, 0xa3, 0x73, 0x2b, + 0xfd, 0x88, 0x70, 0xff, 0x67, 0x13, 0x9e, 0xc5, 0xd8, 0x51, 0x9e, 0x85, 0x1e, 0x87, 0xab, 0x75, + 0x59, 0x89, 0x30, 0x35, 0x0e, 0x57, 0xaf, 0x6c, 0x62, 0x4d, 0xd3, 0xdf, 0x18, 0x57, 0x32, 0x32, + 0xc6, 0x30, 0xb2, 0x31, 0x96, 0x66, 0x61, 0x7c, 0xa0, 0x59, 0x90, 0x3b, 0x37, 0x13, 0x03, 0x77, + 0x6e, 0xde, 0x80, 0x29, 0xcf, 0xdf, 0x21, 0xa1, 0x17, 0x93, 0x1a, 0x1b, 0x0b, 0xe2, 0xae, 0x5f, + 0x35, 0x15, 0xaf, 0x24, 0xb0, 0x38, 0x45, 0x9d, 0xb4, 0x65, 0x53, 0x43, 0xd8, 0xb2, 0x01, 0x33, + 0xc8, 0xa9, 0x6c, 0x66, 0x90, 0xd3, 0xc7, 0x9f, 0x41, 0xa6, 0x4f, 0x74, 0x06, 0x41, 0x99, 0xcc, + 0x20, 0xc3, 0x18, 0x67, 0x73, 0x11, 0x76, 0xf6, 0x88, 0x45, 0xd8, 0xa0, 0xe9, 0xe3, 0xdc, 0xc3, + 0x4e, 0x1f, 0xf6, 0x97, 0x73, 0x70, 0x4e, 0xdb, 0x4e, 0xda, 0x63, 0xbd, 0x3a, 0xb5, 0x1e, 0xac, + 0x00, 0x2d, 0x0f, 0xfb, 0x30, 0x82, 0xc5, 0x74, 0xdc, 0x99, 0xc2, 0x60, 0x83, 0x8a, 0xc5, 0x5c, + 0x91, 0x90, 0x95, 0x72, 0x49, 0x1b, 0xd6, 0x45, 0x01, 0xc7, 0x8a, 0x82, 0xf6, 0x09, 0xfa, 0x5b, + 0xc4, 0xb1, 0xa6, 0xd3, 0xbb, 0x17, 0x35, 0x0a, 0x9b, 0x74, 0xe8, 0x45, 0x2e, 0x84, 0x0d, 0x6a, + 0x6a, 0x5c, 0x27, 0xc4, 0xd5, 0x0a, 0x72, 0x1c, 0x2b, 0xac, 0x54, 0x87, 0x05, 0xd7, 0x15, 0x7b, + 0xd5, 0x61, 0x87, 0x5c, 0x8a, 0xc2, 0xfe, 0x3f, 0x16, 0x3c, 0xd3, 0xb7, 0x29, 0x1e, 0xc1, 0x84, + 0xb9, 0x9f, 0x9c, 0x30, 0x37, 0xb3, 0x72, 0xeb, 0x8d, 0xb7, 0x18, 0x30, 0x79, 0xfe, 0x07, 0x0b, + 0xa6, 0x34, 0xfd, 0x23, 0x78, 0x55, 0x2f, 0xf9, 0xaa, 0xd9, 0xad, 0x60, 0x2a, 0x3d, 0xef, 0xf6, + 0x27, 0xec, 0xdd, 0xf8, 0x59, 0xc1, 0x82, 0x2b, 0xaf, 0x66, 0x3e, 0x62, 0x8f, 0xbc, 0x0b, 0x25, + 0x56, 0xfd, 0x34, 0xca, 0xe6, 0xcc, 0x22, 0x29, 0x9f, 0x45, 0xcd, 0xea, 0x33, 0x0b, 0xf6, 0x37, + 0xc2, 0x42, 0x20, 0x2b, 0x34, 0xe4, 0x45, 0xd4, 0x02, 0xd7, 0x44, 0x98, 0x9a, 0x2e, 0x34, 0x24, + 0xe0, 0x58, 0x51, 0xd8, 0x2d, 0x98, 0x49, 0x32, 0x5f, 0x22, 0x75, 0x76, 0x34, 0x3c, 0xd4, 0x6b, + 0xce, 0x43, 0xc5, 0x61, 0x4f, 0xad, 0x76, 0x9c, 0xf4, 0x6d, 0x3c, 0x0b, 0x12, 0x81, 0x35, 0x8d, + 0xfd, 0xdb, 0x16, 0x9c, 0xe9, 0xf3, 0x32, 0x19, 0x86, 0xe7, 0xc5, 0xda, 0x0a, 0x0c, 0xb8, 0x33, + 0xbb, 0x46, 0xea, 0x8e, 0x3c, 0x7c, 0x34, 0xec, 0xe4, 0x12, 0x07, 0x63, 0x89, 0xb7, 0xff, 0x87, + 0x05, 0xa7, 0x92, 0xba, 0x46, 0xe8, 0x1a, 0x20, 0xfe, 0x32, 0x4b, 0x5e, 0xe4, 0x06, 0x7b, 0x24, + 0xec, 0xd2, 0x37, 0xe7, 0x5a, 0x9f, 0x17, 0x9c, 0xd0, 0x42, 0x0f, 0x05, 0xee, 0xf3, 0x14, 0x2b, + 0x84, 0x52, 0x53, 0xad, 0x2d, 0x7b, 0xca, 0xad, 0x2c, 0x7b, 0x8a, 0xfe, 0x98, 0xe6, 0x01, 0x8d, + 0x12, 0x89, 0x4d, 0xf9, 0xf6, 0xfb, 0x05, 0x50, 0xf1, 0xbb, 0xec, 0x98, 0x2b, 0xa3, 0x43, 0xc2, + 0xc4, 0x95, 0x4d, 0xf9, 0x11, 0x2e, 0xf1, 0x2e, 0x3c, 0xe8, 0x08, 0x8a, 0xef, 0x12, 0x98, 0x9b, + 0x71, 0xea, 0x0d, 0xb7, 0x34, 0x0a, 0x9b, 0x74, 0x54, 0x93, 0xa6, 0xb7, 0x47, 0xf8, 0x43, 0xa5, + 0xa4, 0x26, 0xab, 0x12, 0x81, 0x35, 0x0d, 0xd5, 0xa4, 0xe6, 0xd5, 0xeb, 0x62, 0xc9, 0xab, 0x34, + 0xa1, 0xad, 0x83, 0x19, 0x86, 0x52, 0xec, 0x04, 0xc1, 0xae, 0xf0, 0x28, 0x15, 0xc5, 0xd5, 0x20, + 0xd8, 0xc5, 0x0c, 0x43, 0x7d, 0x20, 0x3f, 0x08, 0x5b, 0xec, 0xb6, 0xa4, 0x9a, 0x92, 0x22, 0x3c, + 0x49, 0xe5, 0x03, 0xdd, 0xe8, 0x25, 0xc1, 0xfd, 0x9e, 0xa3, 0x3d, 0xb0, 0x1d, 0x92, 0x9a, 0xe7, + 0xc6, 0x26, 0x37, 0x48, 0xf6, 0xc0, 0x8d, 0x1e, 0x0a, 0xdc, 0xe7, 0x29, 0xb4, 0x00, 0xa7, 0x64, + 0xfc, 0xb5, 0x4c, 0x51, 0x1b, 0x4f, 0xa6, 0xc4, 0xe0, 0x24, 0x1a, 0xa7, 0xe9, 0xa9, 0xb5, 0x69, + 0x89, 0xec, 0x54, 0xe6, 0x78, 0x1a, 0xd6, 0x46, 0x66, 0xad, 0x62, 0x45, 0x61, 0x7f, 0x21, 0x4f, + 0x67, 0xc7, 0x01, 0x55, 0x6a, 0x1f, 0xd9, 0xa1, 0x74, 0xb2, 0x47, 0x16, 0x86, 0xe8, 0x91, 0xaf, + 0xc2, 0xc4, 0x9d, 0x28, 0xf0, 0xd5, 0x81, 0x6f, 0x71, 0xe0, 0x81, 0xaf, 0x41, 0xd5, 0xff, 0xc0, + 0xb7, 0x94, 0xd5, 0x81, 0xef, 0xd8, 0x43, 0x1e, 0xf8, 0xfe, 0x41, 0x11, 0x54, 0x9d, 0xc7, 0x1b, + 0x24, 0xbe, 0x17, 0x84, 0xbb, 0x9e, 0xdf, 0x60, 0x71, 0xeb, 0xdf, 0xb2, 0x60, 0x82, 0x8f, 0x97, + 0x55, 0x33, 0x86, 0xb5, 0x9e, 0x51, 0x3d, 0xc2, 0x84, 0xb0, 0xb9, 0x2d, 0x43, 0x50, 0xaa, 0x18, + 0xbf, 0x89, 0xc2, 0x09, 0x8d, 0xd0, 0xcf, 0x03, 0xc8, 0xfd, 0xc1, 0x7a, 0x46, 0x37, 0xea, 0xab, + 0x5b, 0x9c, 0x48, 0x5d, 0xfb, 0xa6, 0x5b, 0x4a, 0x08, 0x36, 0x04, 0xa2, 0x2f, 0xa7, 0x6f, 0x93, + 0xfb, 0xdc, 0x89, 0xb4, 0xcd, 0x30, 0xd1, 0xbd, 0x18, 0xc6, 0x3c, 0xbf, 0x41, 0xfb, 0x89, 0x38, + 0x23, 0xff, 0x48, 0xbf, 0x9c, 0x8f, 0xd5, 0xc0, 0xa9, 0x55, 0x9d, 0xa6, 0xe3, 0xbb, 0x24, 0x5c, + 0xe1, 0xe4, 0xe6, 0xed, 0x30, 0x0c, 0x80, 0x25, 0xa3, 0x9e, 0x82, 0x9b, 0xc5, 0x61, 0x0a, 0x6e, + 0x9e, 0xff, 0x04, 0x4c, 0xf7, 0x7c, 0xcc, 0x91, 0x82, 0x79, 0x1f, 0x3e, 0x0e, 0xd8, 0xfe, 0x17, + 0x25, 0x3d, 0x69, 0xdd, 0x08, 0x6a, 0xbc, 0xec, 0x63, 0xa8, 0xbf, 0xa8, 0xf0, 0x3d, 0x33, 0xec, + 0x22, 0xc6, 0x0d, 0x33, 0x0a, 0x88, 0x4d, 0x91, 0xb4, 0x8f, 0xb6, 0x9d, 0x90, 0xf8, 0x27, 0xdd, + 0x47, 0x37, 0x94, 0x10, 0x6c, 0x08, 0x44, 0x3b, 0x89, 0x68, 0xbe, 0x2b, 0xc7, 0x8f, 0xe6, 0x63, + 0x29, 0xa5, 0xfd, 0xea, 0xda, 0x7d, 0xc3, 0x82, 0x29, 0x3f, 0xd1, 0x73, 0xc5, 0x79, 0xc9, 0xd6, + 0x49, 0x8c, 0x0a, 0x5e, 0x26, 0x38, 0x09, 0xc3, 0x29, 0xf9, 0xfd, 0xa6, 0xb4, 0xe2, 0x88, 0x53, + 0x9a, 0xae, 0x1f, 0x5b, 0x1a, 0x54, 0x3f, 0x16, 0xf9, 0xaa, 0xe2, 0xf5, 0x58, 0xe6, 0x15, 0xaf, + 0xa1, 0x4f, 0xb5, 0xeb, 0xdb, 0x50, 0x71, 0x43, 0xe2, 0xc4, 0x0f, 0x59, 0xfc, 0x98, 0x1d, 0x16, + 0x2f, 0x4a, 0x06, 0x58, 0xf3, 0xb2, 0xff, 0x7d, 0x1e, 0x4e, 0xcb, 0x16, 0x91, 0x91, 0x4e, 0x74, + 0x7e, 0xe4, 0x72, 0xb5, 0x73, 0xab, 0xe6, 0xc7, 0xab, 0x12, 0x81, 0x35, 0x0d, 0xf5, 0xc7, 0x3a, + 0x11, 0x59, 0x6f, 0x13, 0x7f, 0xd5, 0xdb, 0x8e, 0xc4, 0x39, 0x9f, 0x1a, 0x28, 0x37, 0x35, 0x0a, + 0x9b, 0x74, 0xd4, 0x19, 0xe7, 0x7e, 0x71, 0x94, 0x0e, 0x1c, 0x14, 0xfe, 0x36, 0x96, 0x78, 0xf4, + 0xeb, 0x7d, 0xcb, 0xe6, 0x67, 0x13, 0x32, 0xdb, 0x13, 0xe0, 0x35, 0x62, 0xbd, 0xfc, 0x77, 0x2c, + 0x38, 0xb5, 0x9b, 0xc8, 0xf9, 0x91, 0x26, 0xf9, 0x98, 0xd9, 0xa9, 0xc9, 0x44, 0x22, 0xdd, 0x85, + 0x93, 0xf0, 0x08, 0xa7, 0xa5, 0xdb, 0xff, 0xcb, 0x02, 0xd3, 0x3c, 0x0d, 0xe7, 0x59, 0x19, 0xf7, + 0xdc, 0xe4, 0x8e, 0xb8, 0xe7, 0x46, 0x3a, 0x61, 0xf9, 0xe1, 0x9c, 0xfe, 0xc2, 0x08, 0x4e, 0x7f, + 0x71, 0xa0, 0xd7, 0xf6, 0x3c, 0xe4, 0x3b, 0x5e, 0x4d, 0xf8, 0xed, 0xfa, 0x54, 0x6f, 0x65, 0x09, + 0x53, 0xb8, 0xfd, 0xbb, 0x45, 0xbd, 0x4e, 0x17, 0x91, 0x9e, 0x3f, 0x14, 0xaf, 0x5d, 0x57, 0xc9, + 0xc6, 0xfc, 0xcd, 0x6f, 0xf4, 0x24, 0x1b, 0xff, 0xc4, 0xe8, 0x81, 0xbc, 0xbc, 0x81, 0x06, 0xe5, + 0x1a, 0x8f, 0x1d, 0x11, 0xc5, 0x7b, 0x07, 0xca, 0x74, 0x69, 0xc3, 0x36, 0xdc, 0xca, 0x09, 0xa5, + 0xca, 0x57, 0x05, 0xfc, 0xfe, 0xc1, 0xec, 0x8f, 0x8f, 0xae, 0x96, 0x7c, 0x1a, 0x2b, 0xfe, 0x28, + 0x82, 0x0a, 0xfd, 0xcd, 0x02, 0x8e, 0xc5, 0xa2, 0xe9, 0xa6, 0xb2, 0x45, 0x12, 0x91, 0x49, 0x34, + 0xb3, 0x96, 0x83, 0x7c, 0xa8, 0xb0, 0x2b, 0x3b, 0x98, 0x50, 0xbe, 0xb6, 0xda, 0x50, 0x61, 0xbf, + 0x12, 0x71, 0xff, 0x60, 0xf6, 0xf5, 0xd1, 0x85, 0xaa, 0xc7, 0xb1, 0x16, 0x61, 0xbf, 0x5b, 0xd0, + 0x7d, 0x57, 0xe4, 0x98, 0xff, 0x50, 0xf4, 0xdd, 0xd7, 0x52, 0x7d, 0xf7, 0x62, 0x4f, 0xdf, 0x9d, + 0xd2, 0x57, 0x4b, 0x24, 0x7a, 0xe3, 0xa3, 0x9e, 0x60, 0x8f, 0x5e, 0xc7, 0x33, 0xcf, 0xe2, 0x6e, + 0xc7, 0x0b, 0x49, 0xb4, 0x11, 0x76, 0x7c, 0xcf, 0x6f, 0x88, 0xbb, 0xeb, 0x0c, 0xcf, 0x22, 0x81, + 0xc6, 0x69, 0x7a, 0x76, 0xef, 0x5d, 0xd7, 0x77, 0x6f, 0x3b, 0x7b, 0xbc, 0x57, 0x19, 0x69, 0xb7, + 0x9b, 0x02, 0x8e, 0x15, 0x85, 0xfd, 0x1d, 0x76, 0xde, 0x6a, 0x64, 0x3a, 0xd0, 0x3e, 0xd1, 0x64, + 0x77, 0xa4, 0xf0, 0x9c, 0x5d, 0xd5, 0x27, 0xf8, 0xc5, 0x28, 0x1c, 0x87, 0xee, 0xc1, 0xd8, 0x36, + 0xaf, 0x39, 0x9e, 0x4d, 0x91, 0x2f, 0x51, 0xc0, 0x9c, 0xd5, 0xe1, 0x94, 0xd5, 0xcc, 0xef, 0xeb, + 0x9f, 0x58, 0x4a, 0xb3, 0xdf, 0x2b, 0xc0, 0xa9, 0xd4, 0x2d, 0x1a, 0x89, 0x92, 0x23, 0xb9, 0x23, + 0x4b, 0x8e, 0x7c, 0x06, 0xa0, 0x46, 0xda, 0xcd, 0xa0, 0xcb, 0xdc, 0x9c, 0xc2, 0xc8, 0x6e, 0x8e, + 0xf2, 0x8c, 0x97, 0x14, 0x17, 0x6c, 0x70, 0x14, 0x89, 0xca, 0xbc, 0x82, 0x49, 0x2a, 0x51, 0xd9, + 0xa8, 0xb3, 0x57, 0x7a, 0xb4, 0x75, 0xf6, 0x3c, 0x38, 0xc5, 0x55, 0x54, 0xf9, 0x04, 0x0f, 0x91, + 0x36, 0xc0, 0x22, 0x51, 0x97, 0x92, 0x6c, 0x70, 0x9a, 0xef, 0xe3, 0xbc, 0x24, 0x07, 0x7d, 0x14, + 0x2a, 0xf2, 0x3b, 0x47, 0x33, 0x15, 0x9d, 0x93, 0x25, 0xbb, 0x01, 0xbb, 0xbc, 0x46, 0xfc, 0xb4, + 0xbf, 0x9e, 0xa3, 0x5e, 0x29, 0xff, 0xa7, 0x72, 0x6b, 0x3f, 0x0c, 0x25, 0xa7, 0x13, 0xef, 0x04, + 0x3d, 0x55, 0xde, 0x17, 0x18, 0x14, 0x0b, 0x2c, 0x5a, 0x85, 0x42, 0x4d, 0xe7, 0x4b, 0x8e, 0xd2, + 0x8a, 0x7a, 0x83, 0xcf, 0x89, 0x09, 0x66, 0x5c, 0xd0, 0x73, 0x50, 0x88, 0x9d, 0x46, 0xe2, 0xfe, + 0xc5, 0x2d, 0xa7, 0x11, 0x61, 0x06, 0x35, 0x27, 0xcd, 0xc2, 0x11, 0x93, 0xe6, 0xeb, 0x30, 0x19, + 0x79, 0x0d, 0xdf, 0x89, 0x3b, 0x21, 0x31, 0x0e, 0x93, 0xf4, 0x99, 0xbe, 0x89, 0xc4, 0x49, 0x5a, + 0xfb, 0xfd, 0x0a, 0x9c, 0xed, 0x77, 0x4f, 0x76, 0xd6, 0x51, 0xe7, 0xfd, 0x64, 0x3c, 0xba, 0xa8, + 0xf3, 0x01, 0xd2, 0x9b, 0x46, 0xd4, 0x79, 0xd3, 0x88, 0x3a, 0xff, 0xb2, 0x05, 0x15, 0x15, 0x6c, + 0x2d, 0x02, 0x46, 0x3f, 0x75, 0x02, 0x77, 0x91, 0x4b, 0x11, 0x22, 0xe6, 0x56, 0xfe, 0xc5, 0x5a, + 0xf8, 0xc9, 0x85, 0xa1, 0x3f, 0x50, 0xa1, 0x91, 0xc2, 0xd0, 0x55, 0x8c, 0x7e, 0x31, 0x8b, 0x18, + 0xfd, 0x01, 0x9f, 0xaa, 0x6f, 0x8c, 0xfe, 0x37, 0x2c, 0x18, 0x77, 0xde, 0xee, 0x84, 0x64, 0x89, + 0xec, 0xad, 0xb7, 0x23, 0x61, 0x60, 0x3f, 0x9d, 0xbd, 0x02, 0x0b, 0x5a, 0x88, 0x28, 0x47, 0xab, + 0x01, 0xd8, 0x54, 0x21, 0x11, 0x93, 0x3f, 0x96, 0x45, 0x4c, 0x7e, 0x3f, 0x75, 0x8e, 0x8c, 0xc9, + 0x7f, 0x1d, 0x26, 0xdd, 0x66, 0xe0, 0x93, 0x8d, 0x30, 0x88, 0x03, 0x37, 0x68, 0x0a, 0x67, 0x5a, + 0x99, 0x84, 0x45, 0x13, 0x89, 0x93, 0xb4, 0x83, 0x02, 0xfa, 0x2b, 0xc7, 0x0d, 0xe8, 0x87, 0xc7, + 0x14, 0xd0, 0xff, 0xe7, 0x39, 0x98, 0x3d, 0xe2, 0xa3, 0xa2, 0xd7, 0x60, 0x22, 0x08, 0x1b, 0x8e, + 0xef, 0xbd, 0xcd, 0xf3, 0x29, 0x8b, 0xc9, 0x72, 0x17, 0xeb, 0x06, 0x0e, 0x27, 0x28, 0x65, 0xc8, + 0x6f, 0x69, 0x40, 0xc8, 0xef, 0xc7, 0x60, 0x3c, 0x26, 0x4e, 0x4b, 0xc4, 0x4a, 0x88, 0x05, 0x90, + 0x3e, 0x50, 0xd2, 0x28, 0x6c, 0xd2, 0xd1, 0x6e, 0x34, 0xe5, 0xb8, 0x2e, 0x89, 0x22, 0x19, 0xd3, + 0x2b, 0x36, 0x67, 0x32, 0x0b, 0x18, 0x66, 0x7b, 0x5e, 0x0b, 0x09, 0x11, 0x38, 0x25, 0x92, 0x2a, + 0xef, 0x34, 0x9b, 0x3c, 0x7c, 0x9f, 0xc8, 0x1b, 0x95, 0x75, 0xf5, 0x05, 0x8d, 0xc2, 0x26, 0x9d, + 0xfd, 0x1b, 0x39, 0x78, 0xfe, 0x81, 0xe6, 0x65, 0xe8, 0x70, 0xeb, 0x4e, 0x44, 0xc2, 0xf4, 0x81, + 0xcc, 0xcd, 0x88, 0x84, 0x98, 0x61, 0x78, 0x2b, 0xb5, 0xdb, 0xc6, 0x55, 0x2e, 0x59, 0x47, 0xf7, + 0xf3, 0x56, 0x4a, 0x88, 0xc0, 0x29, 0x91, 0xe9, 0x56, 0x2a, 0x0c, 0xd9, 0x4a, 0xff, 0x20, 0x07, + 0x2f, 0x0c, 0x61, 0x84, 0x33, 0xcc, 0x82, 0x48, 0x66, 0x91, 0xe4, 0x1f, 0x4f, 0x16, 0xc9, 0xc3, + 0x36, 0xd7, 0x77, 0x72, 0x70, 0x7e, 0xb0, 0x2d, 0x44, 0x3f, 0x49, 0x17, 0x51, 0x32, 0xd8, 0xc2, + 0xcc, 0x40, 0x39, 0xc3, 0x17, 0x50, 0x09, 0x14, 0x4e, 0xd3, 0xa2, 0x39, 0x80, 0xb6, 0x13, 0xef, + 0x44, 0x97, 0xf7, 0xbd, 0x28, 0x16, 0xb9, 0x93, 0x53, 0x7c, 0x2b, 0x5c, 0x42, 0xb1, 0x41, 0x41, + 0xc5, 0xb1, 0x7f, 0x4b, 0xc1, 0x8d, 0x20, 0xe6, 0x0f, 0x71, 0x3f, 0xee, 0x8c, 0xac, 0xf7, 0x67, + 0xa0, 0x70, 0x9a, 0x96, 0x8a, 0x63, 0x87, 0x2d, 0x5c, 0x51, 0x71, 0x5d, 0x3c, 0x15, 0xb7, 0xaa, + 0xa0, 0xd8, 0xa0, 0x48, 0xe7, 0xd6, 0x14, 0x87, 0xc8, 0xad, 0xf9, 0x27, 0x39, 0x78, 0x66, 0xe0, + 0x5c, 0x3a, 0xdc, 0x00, 0x7c, 0xf2, 0x92, 0x6a, 0x1e, 0xae, 0xef, 0x8c, 0x98, 0x2a, 0xf2, 0xa7, + 0x03, 0x7a, 0x9a, 0x48, 0x15, 0x49, 0x4f, 0x15, 0xd6, 0xa8, 0x53, 0xc5, 0x13, 0xd4, 0x9e, 0x3d, + 0xd9, 0x21, 0x85, 0x11, 0xb2, 0x43, 0x52, 0x1f, 0xa3, 0x38, 0xe4, 0x40, 0xfe, 0xee, 0xe0, 0xe6, + 0xa5, 0xbe, 0xf7, 0x50, 0xdb, 0x53, 0x4b, 0x70, 0xda, 0xf3, 0x59, 0xed, 0xd7, 0xcd, 0xce, 0xb6, + 0xc8, 0xac, 0xcd, 0x25, 0xaf, 0x35, 0x5a, 0x49, 0xe1, 0x71, 0xcf, 0x13, 0x4f, 0x60, 0xb6, 0xce, + 0x43, 0x36, 0xe9, 0x67, 0xa0, 0xa2, 0x78, 0xf3, 0xc8, 0x48, 0xf5, 0x41, 0x7b, 0x22, 0x23, 0xd5, + 0xd7, 0x34, 0xa8, 0x68, 0x4b, 0xec, 0x92, 0x6e, 0xba, 0x67, 0x5e, 0x27, 0x5d, 0x76, 0x4a, 0x6a, + 0xff, 0x18, 0x4c, 0xa8, 0x45, 0xe4, 0xb0, 0xb5, 0x49, 0xed, 0x77, 0x4b, 0x30, 0x99, 0xa8, 0xa0, + 0x90, 0xd8, 0xb3, 0xb1, 0x8e, 0xdc, 0xb3, 0x61, 0xd1, 0xa9, 0x1d, 0x5f, 0x56, 0xff, 0x35, 0xa2, + 0x53, 0x3b, 0x3e, 0xc1, 0x1c, 0x47, 0x97, 0xee, 0xb5, 0xb0, 0x8b, 0x3b, 0xbe, 0x88, 0x48, 0x53, + 0x4b, 0xf7, 0x25, 0x06, 0xc5, 0x02, 0x8b, 0x3e, 0x6f, 0xc1, 0x44, 0xc4, 0x36, 0x04, 0xf9, 0x8e, + 0x97, 0xf8, 0xa0, 0xd7, 0xb2, 0xb8, 0xbd, 0x56, 0x54, 0x0b, 0x61, 0x87, 0xd9, 0x26, 0x04, 0x27, + 0x24, 0xa2, 0x2f, 0x59, 0xe6, 0xbd, 0xbd, 0xa5, 0x2c, 0x22, 0x29, 0xd3, 0x05, 0x2a, 0xf8, 0x56, + 0xc9, 0x83, 0xaf, 0xef, 0xd5, 0xd7, 0x79, 0x8f, 0x3d, 0xba, 0xeb, 0xbc, 0x3f, 0x0a, 0x95, 0x96, + 0xe3, 0x7b, 0x75, 0x12, 0xc5, 0x7c, 0x87, 0x48, 0xd6, 0xcd, 0x91, 0x40, 0xac, 0xf1, 0x74, 0xb2, + 0x8b, 0xd8, 0x8b, 0xc5, 0xc6, 0x96, 0x0e, 0x9b, 0xec, 0x36, 0x35, 0x18, 0x9b, 0x34, 0xe6, 0xfe, + 0x13, 0x3c, 0xd6, 0xfd, 0xa7, 0xf1, 0x23, 0xf6, 0x9f, 0xfe, 0x91, 0x05, 0xe7, 0xfa, 0x7e, 0xb5, + 0x27, 0x37, 0x46, 0xc9, 0x7e, 0x3f, 0x0f, 0x67, 0xfa, 0x94, 0x42, 0x41, 0xdd, 0x13, 0xbb, 0x87, + 0x5a, 0xd4, 0x5a, 0x99, 0x1c, 0xd8, 0x89, 0x47, 0xdb, 0xfd, 0xd5, 0x3b, 0xb0, 0xf9, 0x47, 0xbb, + 0x03, 0x6b, 0x74, 0xcb, 0xc2, 0x63, 0xed, 0x96, 0xc5, 0x23, 0xba, 0xe5, 0xfb, 0x79, 0x30, 0xae, + 0x95, 0x47, 0xbf, 0x60, 0x96, 0x27, 0xb2, 0xb2, 0x2a, 0xa5, 0xc3, 0x99, 0xab, 0xf2, 0x46, 0x5c, + 0x9d, 0x7e, 0xd5, 0x8e, 0xd2, 0x16, 0x20, 0x37, 0x84, 0x05, 0x68, 0xca, 0x3a, 0x50, 0xf9, 0xec, + 0xeb, 0x40, 0x55, 0xd2, 0x35, 0xa0, 0xd0, 0xef, 0x58, 0x30, 0xd3, 0x1a, 0x50, 0xaf, 0x30, 0x9b, + 0xf4, 0xfc, 0x41, 0xd5, 0x10, 0xab, 0xcf, 0x1d, 0x1e, 0xcc, 0x0e, 0x2c, 0x13, 0x89, 0x07, 0x6a, + 0x65, 0xff, 0x2d, 0x8b, 0x8f, 0xe2, 0xd4, 0x57, 0xd0, 0xd3, 0xac, 0xf5, 0x80, 0x69, 0xf6, 0x25, + 0x76, 0xd3, 0x59, 0xfd, 0x2a, 0x71, 0x9a, 0x62, 0x3a, 0x36, 0x2f, 0x2d, 0x63, 0x70, 0xac, 0x28, + 0xd8, 0xdd, 0x04, 0xcd, 0x66, 0x70, 0xef, 0x72, 0xab, 0x1d, 0x77, 0xc5, 0xc4, 0xac, 0xef, 0x26, + 0x50, 0x18, 0x6c, 0x50, 0xd9, 0x7f, 0x27, 0xc7, 0x7b, 0xa0, 0x38, 0xa4, 0x7c, 0x2d, 0x55, 0x08, + 0x7b, 0xf8, 0xf3, 0xbd, 0x9f, 0x03, 0x70, 0xd5, 0x25, 0x47, 0xd9, 0x5c, 0x52, 0xaf, 0x2f, 0x4d, + 0x32, 0x6f, 0x4e, 0x97, 0x30, 0x6c, 0xc8, 0x4b, 0x18, 0xa6, 0xfc, 0x91, 0x86, 0x29, 0x31, 0x46, + 0x0b, 0x47, 0x8c, 0xd1, 0x3f, 0xb7, 0x20, 0xe1, 0x5e, 0xa0, 0x36, 0x14, 0xa9, 0xba, 0xdd, 0x6c, + 0xee, 0x6f, 0x32, 0x59, 0x53, 0x3b, 0x23, 0xba, 0x3d, 0xfb, 0x89, 0xb9, 0x20, 0xd4, 0x14, 0x67, + 0x99, 0xb9, 0x2c, 0xee, 0x18, 0x33, 0x05, 0x5e, 0x0d, 0x82, 0x5d, 0x7e, 0x04, 0xa2, 0xcf, 0x45, + 0xed, 0xd7, 0x60, 0xba, 0x47, 0x29, 0x56, 0xf3, 0x36, 0x90, 0x97, 0x56, 0x19, 0xdd, 0x95, 0x55, + 0xe0, 0xc6, 0x1c, 0x67, 0x7f, 0xc7, 0x82, 0xd3, 0x69, 0xf6, 0xe8, 0x9b, 0x16, 0x4c, 0x47, 0x69, + 0x7e, 0x27, 0xd5, 0x76, 0x2a, 0xce, 0xa7, 0x07, 0x85, 0x7b, 0x95, 0xb0, 0xff, 0xbf, 0xe8, 0xfc, + 0xb7, 0x3d, 0xbf, 0x16, 0xdc, 0x53, 0xb3, 0xbc, 0x35, 0x70, 0x96, 0xa7, 0xe3, 0xd1, 0xdd, 0x21, + 0xb5, 0x4e, 0xb3, 0x27, 0x93, 0x69, 0x53, 0xc0, 0xb1, 0xa2, 0x48, 0xdc, 0x10, 0x9d, 0x3f, 0xf2, + 0x86, 0xe8, 0x57, 0x61, 0xc2, 0xbc, 0x98, 0x4d, 0xf4, 0x4b, 0xe6, 0xdd, 0x9a, 0x77, 0xb8, 0xe1, + 0x04, 0x55, 0xea, 0x6a, 0xde, 0xe2, 0x91, 0x57, 0xf3, 0xbe, 0x08, 0x65, 0x71, 0xcd, 0xac, 0x8c, + 0x86, 0xe3, 0x69, 0x52, 0x02, 0x86, 0x15, 0x96, 0x5a, 0x93, 0x96, 0xe3, 0x77, 0x9c, 0x26, 0x6d, + 0x21, 0x91, 0x8f, 0xa9, 0x86, 0xe1, 0x9a, 0xc2, 0x60, 0x83, 0x8a, 0xbe, 0x71, 0xec, 0xb5, 0xc8, + 0x5b, 0x81, 0x2f, 0xe3, 0x48, 0xf4, 0x06, 0xb1, 0x80, 0x63, 0x45, 0x61, 0xff, 0x37, 0x0b, 0xd2, + 0x77, 0x64, 0x26, 0xb6, 0x0c, 0xac, 0x23, 0x73, 0x40, 0x93, 0xd9, 0x68, 0xb9, 0xa1, 0xb2, 0xd1, + 0xcc, 0x44, 0xb1, 0xfc, 0x03, 0x13, 0xc5, 0x7e, 0x44, 0xdf, 0x9c, 0xc0, 0x33, 0xca, 0xc6, 0xfb, + 0xdd, 0x9a, 0x80, 0x6c, 0x28, 0xb9, 0x8e, 0xca, 0xec, 0x9f, 0xe0, 0x8e, 0xf8, 0xe2, 0x02, 0x23, + 0x12, 0x98, 0xea, 0xf6, 0x7b, 0xdf, 0xbf, 0xf0, 0xa1, 0xef, 0x7e, 0xff, 0xc2, 0x87, 0xfe, 0xf8, + 0xfb, 0x17, 0x3e, 0xf4, 0xf9, 0xc3, 0x0b, 0xd6, 0x7b, 0x87, 0x17, 0xac, 0xef, 0x1e, 0x5e, 0xb0, + 0xfe, 0xf8, 0xf0, 0x82, 0xf5, 0xfe, 0xe1, 0x05, 0xeb, 0x1b, 0xff, 0xf9, 0xc2, 0x87, 0xde, 0xea, + 0x1b, 0xf7, 0x43, 0x7f, 0xbc, 0xec, 0xd6, 0xe6, 0xf7, 0x2e, 0xb1, 0xd0, 0x13, 0x3a, 0x1a, 0xe6, + 0x8d, 0x2e, 0x30, 0x2f, 0x47, 0xc3, 0x5f, 0x04, 0x00, 0x00, 0xff, 0xff, 0xa3, 0x8e, 0x81, 0x82, + 0x37, 0xbc, 0x00, 0x00, } func (m *AWSAuthConfig) Marshal() (dAtA []byte, err error) { @@ -5678,6 +5717,11 @@ func (m *ApplicationSource) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + i -= len(m.Ref) + copy(dAtA[i:], m.Ref) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Ref))) + i-- + dAtA[i] = 0x6a i -= len(m.Chart) copy(dAtA[i:], m.Chart) i = encodeVarintGenerated(dAtA, i, uint64(len(m.Chart))) @@ -6214,6 +6258,20 @@ func (m *ApplicationSpec) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.Sources) > 0 { + for iNdEx := len(m.Sources) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Sources[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x42 + } + } if m.RevisionHistoryLimit != nil { i = encodeVarintGenerated(dAtA, i, uint64(*m.RevisionHistoryLimit)) i-- @@ -6274,16 +6332,18 @@ func (m *ApplicationSpec) MarshalToSizedBuffer(dAtA []byte) (int, error) { } i-- dAtA[i] = 0x12 - { - size, err := m.Source.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err + if m.Source != nil { + { + size, err := m.Source.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0xa } - i-- - dAtA[i] = 0xa return len(dAtA) - i, nil } @@ -6307,6 +6367,15 @@ func (m *ApplicationStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.SourceTypes) > 0 { + for iNdEx := len(m.SourceTypes) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.SourceTypes[iNdEx]) + copy(dAtA[i:], m.SourceTypes[iNdEx]) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.SourceTypes[iNdEx]))) + i-- + dAtA[i] = 0x62 + } + } i -= len(m.ResourceHealthSource) copy(dAtA[i:], m.ResourceHealthSource) i = encodeVarintGenerated(dAtA, i, uint64(len(m.ResourceHealthSource))) @@ -7153,6 +7222,20 @@ func (m *ComparedTo) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.Sources) > 0 { + for iNdEx := len(m.Sources) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Sources[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + } { size, err := m.Destination.MarshalToSizedBuffer(dAtA[:i]) if err != nil { @@ -9270,6 +9353,49 @@ func (m *PullRequestGeneratorGithub) MarshalToSizedBuffer(dAtA []byte) (int, err return len(dAtA) - i, nil } +func (m *RefTarget) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *RefTarget) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *RefTarget) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + i -= len(m.Chart) + copy(dAtA[i:], m.Chart) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Chart))) + i-- + dAtA[i] = 0x1a + i -= len(m.TargetRevision) + copy(dAtA[i:], m.TargetRevision) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.TargetRevision))) + i-- + dAtA[i] = 0x12 + { + size, err := m.Repo.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + func (m *RepoCreds) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -10590,6 +10716,29 @@ func (m *RevisionHistory) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + 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 = encodeVarintGenerated(dAtA, i, uint64(len(m.Revisions[iNdEx]))) + i-- + dAtA[i] = 0x4a + } + } + if len(m.Sources) > 0 { + for iNdEx := len(m.Sources) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Sources[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x42 + } + } if m.DeployStartedAt != nil { { size, err := m.DeployStartedAt.MarshalToSizedBuffer(dAtA[:i]) @@ -11306,6 +11455,29 @@ func (m *SyncOperation) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + 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 = encodeVarintGenerated(dAtA, i, uint64(len(m.Revisions[iNdEx]))) + i-- + dAtA[i] = 0x5a + } + } + if len(m.Sources) > 0 { + for iNdEx := len(m.Sources) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Sources[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x52 + } + } if len(m.SyncOptions) > 0 { for iNdEx := len(m.SyncOptions) - 1; iNdEx >= 0; iNdEx-- { i -= len(m.SyncOptions[iNdEx]) @@ -11449,6 +11621,29 @@ func (m *SyncOperationResult) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + 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 = encodeVarintGenerated(dAtA, i, uint64(len(m.Revisions[iNdEx]))) + i-- + dAtA[i] = 0x2a + } + } + if len(m.Sources) > 0 { + for iNdEx := len(m.Sources) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Sources[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + } + } { size, err := m.Source.MarshalToSizedBuffer(dAtA[:i]) if err != nil { @@ -11616,6 +11811,15 @@ func (m *SyncStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + 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 = encodeVarintGenerated(dAtA, i, uint64(len(m.Revisions[iNdEx]))) + i-- + dAtA[i] = 0x22 + } + } i -= len(m.Revision) copy(dAtA[i:], m.Revision) i = encodeVarintGenerated(dAtA, i, uint64(len(m.Revision))) @@ -12404,6 +12608,8 @@ func (m *ApplicationSource) Size() (n int) { } l = len(m.Chart) n += 1 + l + sovGenerated(uint64(l)) + l = len(m.Ref) + n += 1 + l + sovGenerated(uint64(l)) return n } @@ -12583,8 +12789,10 @@ func (m *ApplicationSpec) Size() (n int) { } var l int _ = l - l = m.Source.Size() - n += 1 + l + sovGenerated(uint64(l)) + if m.Source != nil { + l = m.Source.Size() + n += 1 + l + sovGenerated(uint64(l)) + } l = m.Destination.Size() n += 1 + l + sovGenerated(uint64(l)) l = len(m.Project) @@ -12608,6 +12816,12 @@ func (m *ApplicationSpec) Size() (n int) { if m.RevisionHistoryLimit != nil { n += 1 + sovGenerated(uint64(*m.RevisionHistoryLimit)) } + if len(m.Sources) > 0 { + for _, e := range m.Sources { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } return n } @@ -12657,6 +12871,12 @@ func (m *ApplicationStatus) Size() (n int) { n += 1 + l + sovGenerated(uint64(l)) l = len(m.ResourceHealthSource) n += 1 + l + sovGenerated(uint64(l)) + if len(m.SourceTypes) > 0 { + for _, s := range m.SourceTypes { + l = len(s) + n += 1 + l + sovGenerated(uint64(l)) + } + } return n } @@ -12936,6 +13156,12 @@ func (m *ComparedTo) Size() (n int) { n += 1 + l + sovGenerated(uint64(l)) l = m.Destination.Size() n += 1 + l + sovGenerated(uint64(l)) + if len(m.Sources) > 0 { + for _, e := range m.Sources { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } return n } @@ -13744,6 +13970,21 @@ func (m *PullRequestGeneratorGithub) Size() (n int) { return n } +func (m *RefTarget) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.Repo.Size() + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.TargetRevision) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.Chart) + n += 1 + l + sovGenerated(uint64(l)) + return n +} + func (m *RepoCreds) Size() (n int) { if m == nil { return 0 @@ -14242,6 +14483,18 @@ func (m *RevisionHistory) Size() (n int) { l = m.DeployStartedAt.Size() n += 1 + l + sovGenerated(uint64(l)) } + if len(m.Sources) > 0 { + for _, e := range m.Sources { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + if len(m.Revisions) > 0 { + for _, s := range m.Revisions { + l = len(s) + n += 1 + l + sovGenerated(uint64(l)) + } + } return n } @@ -14521,6 +14774,18 @@ func (m *SyncOperation) Size() (n int) { n += 1 + l + sovGenerated(uint64(l)) } } + if len(m.Sources) > 0 { + for _, e := range m.Sources { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + if len(m.Revisions) > 0 { + for _, s := range m.Revisions { + l = len(s) + n += 1 + l + sovGenerated(uint64(l)) + } + } return n } @@ -14557,6 +14822,18 @@ func (m *SyncOperationResult) Size() (n int) { n += 1 + l + sovGenerated(uint64(l)) l = m.Source.Size() n += 1 + l + sovGenerated(uint64(l)) + if len(m.Sources) > 0 { + for _, e := range m.Sources { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + if len(m.Revisions) > 0 { + for _, s := range m.Revisions { + l = len(s) + n += 1 + l + sovGenerated(uint64(l)) + } + } return n } @@ -14611,6 +14888,12 @@ func (m *SyncStatus) Size() (n int) { n += 1 + l + sovGenerated(uint64(l)) l = len(m.Revision) n += 1 + l + sovGenerated(uint64(l)) + if len(m.Revisions) > 0 { + for _, s := range m.Revisions { + l = len(s) + n += 1 + l + sovGenerated(uint64(l)) + } + } return n } @@ -15086,6 +15369,7 @@ func (this *ApplicationSource) String() string { `Directory:` + strings.Replace(this.Directory.String(), "ApplicationSourceDirectory", "ApplicationSourceDirectory", 1) + `,`, `Plugin:` + strings.Replace(this.Plugin.String(), "ApplicationSourcePlugin", "ApplicationSourcePlugin", 1) + `,`, `Chart:` + fmt.Sprintf("%v", this.Chart) + `,`, + `Ref:` + fmt.Sprintf("%v", this.Ref) + `,`, `}`, }, "") return s @@ -15249,14 +15533,20 @@ func (this *ApplicationSpec) String() string { repeatedStringForInfo += strings.Replace(strings.Replace(f.String(), "Info", "Info", 1), `&`, ``, 1) + "," } repeatedStringForInfo += "}" + repeatedStringForSources := "[]ApplicationSource{" + for _, f := range this.Sources { + repeatedStringForSources += strings.Replace(strings.Replace(f.String(), "ApplicationSource", "ApplicationSource", 1), `&`, ``, 1) + "," + } + repeatedStringForSources += "}" s := strings.Join([]string{`&ApplicationSpec{`, - `Source:` + strings.Replace(strings.Replace(this.Source.String(), "ApplicationSource", "ApplicationSource", 1), `&`, ``, 1) + `,`, + `Source:` + strings.Replace(this.Source.String(), "ApplicationSource", "ApplicationSource", 1) + `,`, `Destination:` + strings.Replace(strings.Replace(this.Destination.String(), "ApplicationDestination", "ApplicationDestination", 1), `&`, ``, 1) + `,`, `Project:` + fmt.Sprintf("%v", this.Project) + `,`, `SyncPolicy:` + strings.Replace(this.SyncPolicy.String(), "SyncPolicy", "SyncPolicy", 1) + `,`, `IgnoreDifferences:` + repeatedStringForIgnoreDifferences + `,`, `Info:` + repeatedStringForInfo + `,`, `RevisionHistoryLimit:` + valueToStringGenerated(this.RevisionHistoryLimit) + `,`, + `Sources:` + repeatedStringForSources + `,`, `}`, }, "") return s @@ -15292,6 +15582,7 @@ func (this *ApplicationStatus) String() string { `SourceType:` + fmt.Sprintf("%v", this.SourceType) + `,`, `Summary:` + strings.Replace(strings.Replace(this.Summary.String(), "ApplicationSummary", "ApplicationSummary", 1), `&`, ``, 1) + `,`, `ResourceHealthSource:` + fmt.Sprintf("%v", this.ResourceHealthSource) + `,`, + `SourceTypes:` + fmt.Sprintf("%v", this.SourceTypes) + `,`, `}`, }, "") return s @@ -15504,9 +15795,15 @@ func (this *ComparedTo) String() string { if this == nil { return "nil" } + repeatedStringForSources := "[]ApplicationSource{" + for _, f := range this.Sources { + repeatedStringForSources += strings.Replace(strings.Replace(f.String(), "ApplicationSource", "ApplicationSource", 1), `&`, ``, 1) + "," + } + repeatedStringForSources += "}" s := strings.Join([]string{`&ComparedTo{`, `Source:` + strings.Replace(strings.Replace(this.Source.String(), "ApplicationSource", "ApplicationSource", 1), `&`, ``, 1) + `,`, `Destination:` + strings.Replace(strings.Replace(this.Destination.String(), "ApplicationDestination", "ApplicationDestination", 1), `&`, ``, 1) + `,`, + `Sources:` + repeatedStringForSources + `,`, `}`, }, "") return s @@ -16145,6 +16442,18 @@ func (this *PullRequestGeneratorGithub) String() string { }, "") return s } +func (this *RefTarget) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&RefTarget{`, + `Repo:` + strings.Replace(strings.Replace(this.Repo.String(), "Repository", "Repository", 1), `&`, ``, 1) + `,`, + `TargetRevision:` + fmt.Sprintf("%v", this.TargetRevision) + `,`, + `Chart:` + fmt.Sprintf("%v", this.Chart) + `,`, + `}`, + }, "") + return s +} func (this *RepoCreds) String() string { if this == nil { return "nil" @@ -16512,12 +16821,19 @@ func (this *RevisionHistory) String() string { if this == nil { return "nil" } + repeatedStringForSources := "[]ApplicationSource{" + for _, f := range this.Sources { + repeatedStringForSources += strings.Replace(strings.Replace(f.String(), "ApplicationSource", "ApplicationSource", 1), `&`, ``, 1) + "," + } + repeatedStringForSources += "}" s := strings.Join([]string{`&RevisionHistory{`, `Revision:` + fmt.Sprintf("%v", this.Revision) + `,`, `DeployedAt:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.DeployedAt), "Time", "v1.Time", 1), `&`, ``, 1) + `,`, `ID:` + fmt.Sprintf("%v", this.ID) + `,`, `Source:` + strings.Replace(strings.Replace(this.Source.String(), "ApplicationSource", "ApplicationSource", 1), `&`, ``, 1) + `,`, `DeployStartedAt:` + strings.Replace(fmt.Sprintf("%v", this.DeployStartedAt), "Time", "v1.Time", 1) + `,`, + `Sources:` + repeatedStringForSources + `,`, + `Revisions:` + fmt.Sprintf("%v", this.Revisions) + `,`, `}`, }, "") return s @@ -16686,6 +17002,11 @@ func (this *SyncOperation) String() string { repeatedStringForResources += strings.Replace(strings.Replace(f.String(), "SyncOperationResource", "SyncOperationResource", 1), `&`, ``, 1) + "," } repeatedStringForResources += "}" + repeatedStringForSources := "[]ApplicationSource{" + for _, f := range this.Sources { + repeatedStringForSources += strings.Replace(strings.Replace(f.String(), "ApplicationSource", "ApplicationSource", 1), `&`, ``, 1) + "," + } + repeatedStringForSources += "}" s := strings.Join([]string{`&SyncOperation{`, `Revision:` + fmt.Sprintf("%v", this.Revision) + `,`, `Prune:` + fmt.Sprintf("%v", this.Prune) + `,`, @@ -16695,6 +17016,8 @@ func (this *SyncOperation) String() string { `Source:` + strings.Replace(this.Source.String(), "ApplicationSource", "ApplicationSource", 1) + `,`, `Manifests:` + fmt.Sprintf("%v", this.Manifests) + `,`, `SyncOptions:` + fmt.Sprintf("%v", this.SyncOptions) + `,`, + `Sources:` + repeatedStringForSources + `,`, + `Revisions:` + fmt.Sprintf("%v", this.Revisions) + `,`, `}`, }, "") return s @@ -16721,10 +17044,17 @@ func (this *SyncOperationResult) String() string { repeatedStringForResources += strings.Replace(f.String(), "ResourceResult", "ResourceResult", 1) + "," } repeatedStringForResources += "}" + repeatedStringForSources := "[]ApplicationSource{" + for _, f := range this.Sources { + repeatedStringForSources += strings.Replace(strings.Replace(f.String(), "ApplicationSource", "ApplicationSource", 1), `&`, ``, 1) + "," + } + repeatedStringForSources += "}" s := strings.Join([]string{`&SyncOperationResult{`, `Resources:` + repeatedStringForResources + `,`, `Revision:` + fmt.Sprintf("%v", this.Revision) + `,`, `Source:` + strings.Replace(strings.Replace(this.Source.String(), "ApplicationSource", "ApplicationSource", 1), `&`, ``, 1) + `,`, + `Sources:` + repeatedStringForSources + `,`, + `Revisions:` + fmt.Sprintf("%v", this.Revisions) + `,`, `}`, }, "") return s @@ -16762,6 +17092,7 @@ func (this *SyncStatus) String() string { `Status:` + fmt.Sprintf("%v", this.Status) + `,`, `ComparedTo:` + strings.Replace(strings.Replace(this.ComparedTo.String(), "ComparedTo", "ComparedTo", 1), `&`, ``, 1) + `,`, `Revision:` + fmt.Sprintf("%v", this.Revision) + `,`, + `Revisions:` + fmt.Sprintf("%v", this.Revisions) + `,`, `}`, }, "") return s @@ -21105,6 +21436,38 @@ func (m *ApplicationSource) Unmarshal(dAtA []byte) error { } m.Chart = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 13: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Ref", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + 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 ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Ref = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -22703,6 +23066,9 @@ func (m *ApplicationSpec) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } + if m.Source == nil { + m.Source = &ApplicationSource{} + } if err := m.Source.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } @@ -22896,6 +23262,40 @@ func (m *ApplicationSpec) Unmarshal(dAtA []byte) error { } } m.RevisionHistoryLimit = &v + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Sources", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Sources = append(m.Sources, ApplicationSource{}) + if err := m.Sources[len(m.Sources)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -23319,6 +23719,38 @@ func (m *ApplicationStatus) Unmarshal(dAtA []byte) error { } m.ResourceHealthSource = ResourceHealthLocation(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 12: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SourceTypes", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + 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 ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.SourceTypes = append(m.SourceTypes, ApplicationSourceType(dAtA[iNdEx:postIndex])) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -25755,6 +26187,40 @@ func (m *ComparedTo) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Sources", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Sources = append(m.Sources, ApplicationSource{}) + if err := m.Sources[len(m.Sources)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -32588,7 +33054,7 @@ func (m *PullRequestGeneratorGithub) Unmarshal(dAtA []byte) error { } return nil } -func (m *RepoCreds) Unmarshal(dAtA []byte) error { +func (m *RefTarget) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -32611,17 +33077,17 @@ func (m *RepoCreds) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: RepoCreds: wiretype end group for non-group") + return fmt.Errorf("proto: RefTarget: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: RepoCreds: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: RefTarget: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field URL", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Repo", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -32631,27 +33097,28 @@ func (m *RepoCreds) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - m.URL = string(dAtA[iNdEx:postIndex]) + if err := m.Repo.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Username", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field TargetRevision", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -32679,11 +33146,11 @@ func (m *RepoCreds) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Username = string(dAtA[iNdEx:postIndex]) + m.TargetRevision = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Password", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Chart", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -32711,11 +33178,61 @@ func (m *RepoCreds) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Password = string(dAtA[iNdEx:postIndex]) + m.Chart = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 4: + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *RepoCreds) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: RepoCreds: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: RepoCreds: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field SSHPrivateKey", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field URL", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -32743,11 +33260,11 @@ func (m *RepoCreds) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.SSHPrivateKey = string(dAtA[iNdEx:postIndex]) + m.URL = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 5: + case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field TLSClientCertData", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Username", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -32775,11 +33292,107 @@ func (m *RepoCreds) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.TLSClientCertData = string(dAtA[iNdEx:postIndex]) + m.Username = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 6: + case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field TLSClientCertKey", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Password", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + 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 ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Password = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SSHPrivateKey", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + 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 ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.SSHPrivateKey = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TLSClientCertData", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + 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 ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.TLSClientCertData = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TLSClientCertKey", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -37640,6 +38253,72 @@ func (m *RevisionHistory) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Sources", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Sources = append(m.Sources, ApplicationSource{}) + if err := m.Sources[len(m.Sources)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 9: + 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 ErrIntOverflowGenerated + } + 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 ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Revisions = append(m.Revisions, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -40061,6 +40740,72 @@ func (m *SyncOperation) Unmarshal(dAtA []byte) error { } m.SyncOptions = append(m.SyncOptions, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex + case 10: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Sources", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Sources = append(m.Sources, ApplicationSource{}) + if err := m.Sources[len(m.Sources)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 11: + 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 ErrIntOverflowGenerated + } + 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 ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Revisions = append(m.Revisions, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -40388,6 +41133,72 @@ func (m *SyncOperationResult) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Sources", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Sources = append(m.Sources, ApplicationSource{}) + if err := m.Sources[len(m.Sources)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 5: + 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 ErrIntOverflowGenerated + } + 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 ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Revisions = append(m.Revisions, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -40835,6 +41646,38 @@ func (m *SyncStatus) Unmarshal(dAtA []byte) error { } m.Revision = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 4: + 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 ErrIntOverflowGenerated + } + 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 ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Revisions = append(m.Revisions, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) diff --git a/pkg/apis/application/v1alpha1/generated.proto b/pkg/apis/application/v1alpha1/generated.proto index 7512246a971d2..a5bd52048cadf 100644 --- a/pkg/apis/application/v1alpha1/generated.proto +++ b/pkg/apis/application/v1alpha1/generated.proto @@ -327,6 +327,9 @@ message ApplicationSource { // Chart is a Helm chart name, and must be specified for applications sourced from a Helm repo. optional string chart = 12; + + // Ref is reference to another source within sources field. This field will not be used if used with a `source` tag. + optional string ref = 13; } // ApplicationSourceDirectory holds options for applications of type plain YAML or Jsonnet @@ -463,6 +466,9 @@ message ApplicationSpec { // Increasing will increase the space used to store the history, so we do not recommend increasing it. // Default is 10. optional int64 revisionHistoryLimit = 7; + + // Sources is a reference to the location of the application's manifests or chart + repeated ApplicationSource sources = 8; } // ApplicationStatus contains status information for the application @@ -500,6 +506,9 @@ message ApplicationStatus { // ResourceHealthSource indicates where the resource health status is stored: inline if not set or appTree optional string resourceHealthSource = 11; + + // SourceTypes specifies the type of the sources included in the application + repeated string sourceTypes = 12; } // ApplicationSummary contains information about URLs and container images used by an application @@ -688,6 +697,9 @@ message ComparedTo { // Destination is a reference to the application's destination used for comparison optional ApplicationDestination destination = 2; + + // Sources is a reference to the application's multiple sources used for comparison + repeated ApplicationSource sources = 3; } // ComponentParameter contains information about component parameter value @@ -1197,6 +1209,14 @@ message PullRequestGeneratorGithub { repeated string labels = 6; } +message RefTarget { + optional Repository repo = 1; + + optional string targetRevision = 2; + + optional string chart = 3; +} + // RepoCreds holds the definition for repository credentials message RepoCreds { // URL is the URL that this credentials matches to @@ -1587,6 +1607,12 @@ message RevisionHistory { // DeployStartedAt holds the time the sync operation started optional k8s.io.apimachinery.pkg.apis.meta.v1.Time deployStartedAt = 7; + + // Sources is a reference to the application sources used for the sync operation + repeated ApplicationSource sources = 8; + + // Revisions holds the revision of each source in sources field the sync was performed against + repeated string revisions = 9; } // RevisionMetadata contains metadata for a specific revision in a Git repository @@ -1800,6 +1826,14 @@ message SyncOperation { // SyncOptions provide per-sync sync-options, e.g. Validate=false repeated string syncOptions = 9; + + // Sources overrides the source definition set in the application. + // This is typically set in a Rollback operation and is nil during a Sync operation + repeated ApplicationSource sources = 10; + + // Revisions is the list of revision (Git) or chart version (Helm) which to sync each source in sources field for the application to + // If omitted, will use the revision specified in app spec. + repeated string revisions = 11; } // SyncOperationResource contains resources to sync. @@ -1823,6 +1857,12 @@ message SyncOperationResult { // Source records the application source information of the sync, used for comparing auto-sync optional ApplicationSource source = 3; + + // Source records the application source information of the sync, used for comparing auto-sync + repeated ApplicationSource sources = 4; + + // Revisions holds the revision this sync operation was performed for respective indexed source in sources field + repeated string revisions = 5; } // SyncPolicy controls when a sync will be performed in response to updates in git @@ -1862,6 +1902,9 @@ message SyncStatus { // Revision contains information about the revision the comparison has been performed to optional string revision = 3; + + // Revisions contains information about the revisions of multiple sources the comparison has been performed to + repeated string revisions = 4; } // SyncStrategy controls the manner in which a sync is performed diff --git a/pkg/apis/application/v1alpha1/openapi_generated.go b/pkg/apis/application/v1alpha1/openapi_generated.go index cd5161341660f..788ccf3b8b5f3 100644 --- a/pkg/apis/application/v1alpha1/openapi_generated.go +++ b/pkg/apis/application/v1alpha1/openapi_generated.go @@ -99,6 +99,7 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.PullRequestGeneratorGitLab": schema_pkg_apis_application_v1alpha1_PullRequestGeneratorGitLab(ref), "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.PullRequestGeneratorGitea": schema_pkg_apis_application_v1alpha1_PullRequestGeneratorGitea(ref), "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.PullRequestGeneratorGithub": schema_pkg_apis_application_v1alpha1_PullRequestGeneratorGithub(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.RefTarget": schema_pkg_apis_application_v1alpha1_RefTarget(ref), "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.RepoCreds": schema_pkg_apis_application_v1alpha1_RepoCreds(ref), "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.RepoCredsList": schema_pkg_apis_application_v1alpha1_RepoCredsList(ref), "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.Repository": schema_pkg_apis_application_v1alpha1_Repository(ref), @@ -1222,6 +1223,13 @@ func schema_pkg_apis_application_v1alpha1_ApplicationSource(ref common.Reference Format: "", }, }, + "ref": { + SchemaProps: spec.SchemaProps{ + Description: "Ref is reference to another source within sources field. This field will not be used if used with a `source` tag.", + Type: []string{"string"}, + Format: "", + }, + }, }, Required: []string{"repoURL"}, }, @@ -1640,7 +1648,6 @@ func schema_pkg_apis_application_v1alpha1_ApplicationSpec(ref common.ReferenceCa "source": { SchemaProps: spec.SchemaProps{ Description: "Source is a reference to the location of the application's manifests or chart", - Default: map[string]interface{}{}, Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSource"), }, }, @@ -1700,8 +1707,22 @@ func schema_pkg_apis_application_v1alpha1_ApplicationSpec(ref common.ReferenceCa Format: "int64", }, }, + "sources": { + SchemaProps: spec.SchemaProps{ + Description: "Sources is a reference to the location of the application's manifests or chart", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSource"), + }, + }, + }, + }, + }, }, - Required: []string{"source", "destination", "project"}, + Required: []string{"destination", "project"}, }, }, Dependencies: []string{ @@ -1811,6 +1832,21 @@ func schema_pkg_apis_application_v1alpha1_ApplicationStatus(ref common.Reference Format: "", }, }, + "sourceTypes": { + SchemaProps: spec.SchemaProps{ + Description: "SourceTypes specifies the type of the sources included in the application", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + }, + }, }, }, }, @@ -2438,8 +2474,22 @@ func schema_pkg_apis_application_v1alpha1_ComparedTo(ref common.ReferenceCallbac Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationDestination"), }, }, + "sources": { + SchemaProps: spec.SchemaProps{ + Description: "Sources is a reference to the application's multiple sources used for comparison", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSource"), + }, + }, + }, + }, + }, }, - Required: []string{"source", "destination"}, + Required: []string{"destination"}, }, }, Dependencies: []string{ @@ -4206,6 +4256,41 @@ func schema_pkg_apis_application_v1alpha1_PullRequestGeneratorGithub(ref common. } } +func schema_pkg_apis_application_v1alpha1_RefTarget(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "Repo": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.Repository"), + }, + }, + "TargetRevision": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "Chart": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + Required: []string{"Repo", "TargetRevision", "Chart"}, + }, + }, + Dependencies: []string{ + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.Repository"}, + } +} + func schema_pkg_apis_application_v1alpha1_RepoCreds(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ @@ -5452,7 +5537,6 @@ func schema_pkg_apis_application_v1alpha1_RevisionHistory(ref common.ReferenceCa "revision": { SchemaProps: spec.SchemaProps{ Description: "Revision holds the revision the sync was performed against", - Default: "", Type: []string{"string"}, Format: "", }, @@ -5485,8 +5569,37 @@ func schema_pkg_apis_application_v1alpha1_RevisionHistory(ref common.ReferenceCa Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.Time"), }, }, + "sources": { + SchemaProps: spec.SchemaProps{ + Description: "Sources is a reference to the application sources used for the sync operation", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSource"), + }, + }, + }, + }, + }, + "revisions": { + SchemaProps: spec.SchemaProps{ + Description: "Revisions holds the revision of each source in sources field the sync was performed against", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + }, + }, }, - Required: []string{"revision", "deployedAt", "id"}, + Required: []string{"deployedAt", "id"}, }, }, Dependencies: []string{ @@ -6127,6 +6240,35 @@ func schema_pkg_apis_application_v1alpha1_SyncOperation(ref common.ReferenceCall }, }, }, + "sources": { + SchemaProps: spec.SchemaProps{ + Description: "Sources overrides the source definition set in the application. This is typically set in a Rollback operation and is nil during a Sync operation", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSource"), + }, + }, + }, + }, + }, + "revisions": { + SchemaProps: spec.SchemaProps{ + Description: "Revisions is the list of revision (Git) or chart version (Helm) which to sync each source in sources field for the application to If omitted, will use the revision specified in app spec.", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + }, + }, }, }, }, @@ -6210,6 +6352,35 @@ func schema_pkg_apis_application_v1alpha1_SyncOperationResult(ref common.Referen Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSource"), }, }, + "sources": { + SchemaProps: spec.SchemaProps{ + Description: "Source records the application source information of the sync, used for comparing auto-sync", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSource"), + }, + }, + }, + }, + }, + "revisions": { + SchemaProps: spec.SchemaProps{ + Description: "Revisions holds the revision this sync operation was performed for respective indexed source in sources field", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + }, + }, }, Required: []string{"revision"}, }, @@ -6330,6 +6501,21 @@ func schema_pkg_apis_application_v1alpha1_SyncStatus(ref common.ReferenceCallbac Format: "", }, }, + "revisions": { + SchemaProps: spec.SchemaProps{ + Description: "Revisions contains information about the revisions of multiple sources the comparison has been performed to", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + }, + }, }, Required: []string{"status"}, }, diff --git a/pkg/apis/application/v1alpha1/types.go b/pkg/apis/application/v1alpha1/types.go index b36bcc727bf2e..79063da09f920 100644 --- a/pkg/apis/application/v1alpha1/types.go +++ b/pkg/apis/application/v1alpha1/types.go @@ -56,7 +56,7 @@ type Application struct { // ApplicationSpec represents desired application state. Contains link to repository with application definition and additional parameters link definition revision. type ApplicationSpec struct { // Source is a reference to the location of the application's manifests or chart - Source ApplicationSource `json:"source" protobuf:"bytes,1,opt,name=source"` + Source *ApplicationSource `json:"source,omitempty" protobuf:"bytes,1,opt,name=source"` // Destination is a reference to the target Kubernetes server and namespace Destination ApplicationDestination `json:"destination" protobuf:"bytes,2,name=destination"` // Project is a reference to the project this application belongs to. @@ -74,6 +74,9 @@ type ApplicationSpec struct { // Increasing will increase the space used to store the history, so we do not recommend increasing it. // Default is 10. RevisionHistoryLimit *int64 `json:"revisionHistoryLimit,omitempty" protobuf:"bytes,7,name=revisionHistoryLimit"` + + // Sources is a reference to the location of the application's manifests or chart + Sources ApplicationSources `json:"sources,omitempty" protobuf:"bytes,8,opt,name=sources"` } type TrackingMethod string @@ -171,6 +174,44 @@ type ApplicationSource struct { Plugin *ApplicationSourcePlugin `json:"plugin,omitempty" protobuf:"bytes,11,opt,name=plugin"` // Chart is a Helm chart name, and must be specified for applications sourced from a Helm repo. Chart string `json:"chart,omitempty" protobuf:"bytes,12,opt,name=chart"` + // Ref is reference to another source within sources field. This field will not be used if used with a `source` tag. + Ref string `json:"ref,omitempty" protobuf:"bytes,13,opt,name=ref"` +} + +// ApplicationSources contains list of required information about the sources of an application +type ApplicationSources []ApplicationSource + +func (a *ApplicationSpec) GetSource() ApplicationSource { + // if Application has multiple sources, return the first source in sources + if a.HasMultipleSources() { + return a.Sources[0] + } + if a.Source != nil { + return *a.Source + } + return ApplicationSource{} +} + +func (a *ApplicationSpec) GetSources() ApplicationSources { + if a.HasMultipleSources() { + return a.Sources + } + if a.Source != nil { + return ApplicationSources{*a.Source} + } + return ApplicationSources{} +} + +func (a *ApplicationSpec) HasMultipleSources() bool { + return a.Sources != nil && len(a.Sources) > 0 +} + +func (a *ApplicationSpec) GetSourcePtr() *ApplicationSource { + // if Application has multiple sources, return the first source in sources + if a.HasMultipleSources() { + return &a.Sources[0] + } + return a.Source } // AllowsConcurrentProcessing returns true if given application source can be processed concurrently @@ -226,6 +267,14 @@ const ( RefreshTypeHard RefreshType = "hard" ) +type RefTarget struct { + Repo Repository `protobuf:"bytes,1,opt,name=repo"` + TargetRevision string `protobuf:"bytes,2,opt,name=targetRevision"` + Chart string `protobuf:"bytes,3,opt,name=chart"` +} + +type RefTargetRevisionMapping map[string]*RefTarget + // ApplicationSourceHelm holds helm specific options type ApplicationSourceHelm struct { // ValuesFiles is a list of Helm value files to use when generating a template @@ -600,6 +649,8 @@ type ApplicationStatus struct { Summary ApplicationSummary `json:"summary,omitempty" protobuf:"bytes,10,opt,name=summary"` // ResourceHealthSource indicates where the resource health status is stored: inline if not set or appTree ResourceHealthSource ResourceHealthLocation `json:"resourceHealthSource,omitempty" protobuf:"bytes,11,opt,name=resourceHealthSource"` + // SourceTypes specifies the type of the sources included in the application + SourceTypes []ApplicationSourceType `json:"sourceTypes,omitempty" protobuf:"bytes,12,opt,name=sourceTypes"` } // JWTTokens represents a list of JWT tokens @@ -688,6 +739,12 @@ type SyncOperation struct { Manifests []string `json:"manifests,omitempty" protobuf:"bytes,8,opt,name=manifests"` // SyncOptions provide per-sync sync-options, e.g. Validate=false SyncOptions SyncOptions `json:"syncOptions,omitempty" protobuf:"bytes,9,opt,name=syncOptions"` + // Sources overrides the source definition set in the application. + // This is typically set in a Rollback operation and is nil during a Sync operation + Sources ApplicationSources `json:"sources,omitempty" protobuf:"bytes,10,opt,name=sources"` + // Revisions is the list of revision (Git) or chart version (Helm) which to sync each source in sources field for the application to + // If omitted, will use the revision specified in app spec. + Revisions []string `json:"revisions,omitempty" protobuf:"bytes,11,opt,name=revisions"` } // IsApplyStrategy returns true if the sync strategy is "apply" @@ -909,6 +966,10 @@ type SyncOperationResult struct { Revision string `json:"revision" protobuf:"bytes,2,opt,name=revision"` // Source records the application source information of the sync, used for comparing auto-sync Source ApplicationSource `json:"source,omitempty" protobuf:"bytes,3,opt,name=source"` + // Source records the application source information of the sync, used for comparing auto-sync + Sources ApplicationSources `json:"sources,omitempty" protobuf:"bytes,4,opt,name=sources"` + // Revisions holds the revision this sync operation was performed for respective indexed source in sources field + Revisions []string `json:"revisions,omitempty" protobuf:"bytes,5,opt,name=revisions"` } // ResourceResult holds the operation result details of a specific resource @@ -971,7 +1032,7 @@ func (r ResourceResults) PruningRequired() (num int) { // RevisionHistory contains history information about a previous sync type RevisionHistory struct { // Revision holds the revision the sync was performed against - Revision string `json:"revision" protobuf:"bytes,2,opt,name=revision"` + Revision string `json:"revision,omitempty" protobuf:"bytes,2,opt,name=revision"` // DeployedAt holds the time the sync operation completed DeployedAt metav1.Time `json:"deployedAt" protobuf:"bytes,4,opt,name=deployedAt"` // ID is an auto incrementing identifier of the RevisionHistory @@ -980,6 +1041,10 @@ type RevisionHistory struct { Source ApplicationSource `json:"source,omitempty" protobuf:"bytes,6,opt,name=source"` // DeployStartedAt holds the time the sync operation started DeployStartedAt *metav1.Time `json:"deployStartedAt,omitempty" protobuf:"bytes,7,opt,name=deployStartedAt"` + // Sources is a reference to the application sources used for the sync operation + Sources ApplicationSources `json:"sources,omitempty" protobuf:"bytes,8,opt,name=sources"` + // Revisions holds the revision of each source in sources field the sync was performed against + Revisions []string `json:"revisions,omitempty" protobuf:"bytes,9,opt,name=revisions"` } // ApplicationWatchEvent contains information about application change. @@ -1062,9 +1127,11 @@ type ApplicationCondition struct { // ComparedTo contains application source and target which was used for resources comparison type ComparedTo struct { // Source is a reference to the application's source used for comparison - Source ApplicationSource `json:"source" protobuf:"bytes,1,opt,name=source"` + Source ApplicationSource `json:"source,omitempty" protobuf:"bytes,1,opt,name=source"` // Destination is a reference to the application's destination used for comparison Destination ApplicationDestination `json:"destination" protobuf:"bytes,2,opt,name=destination"` + // Sources is a reference to the application's multiple sources used for comparison + Sources ApplicationSources `json:"sources,omitempty" protobuf:"bytes,3,opt,name=sources"` } // SyncStatus contains information about the currently observed live and desired states of an application @@ -1075,6 +1142,8 @@ type SyncStatus struct { ComparedTo ComparedTo `json:"comparedTo,omitempty" protobuf:"bytes,2,opt,name=comparedTo"` // Revision contains information about the revision the comparison has been performed to Revision string `json:"revision,omitempty" protobuf:"bytes,3,opt,name=revision"` + // Revisions contains information about the revisions of multiple sources the comparison has been performed to + Revisions []string `json:"revisions,omitempty" protobuf:"bytes,4,opt,name=revisions"` } // HealthStatus contains information about the currently observed health state of an application or resource @@ -2187,7 +2256,6 @@ func (app *Application) IsRefreshRequested() (RefreshType, bool) { if annotations == nil { return refreshType, false } - typeStr, ok := annotations[AnnotationKeyRefresh] if !ok { return refreshType, false @@ -2196,7 +2264,6 @@ func (app *Application) IsRefreshRequested() (RefreshType, bool) { if typeStr == string(RefreshTypeHard) { refreshType = RefreshTypeHard } - return refreshType, true } diff --git a/pkg/apis/application/v1alpha1/types_test.go b/pkg/apis/application/v1alpha1/types_test.go index e69127f0d24cf..0546f007d18bf 100644 --- a/pkg/apis/application/v1alpha1/types_test.go +++ b/pkg/apis/application/v1alpha1/types_test.go @@ -3304,3 +3304,83 @@ func TestApplicationSourcePluginParameters_Environ_all(t *testing.T) { require.NoError(t, err) assert.Contains(t, environ, fmt.Sprintf("ARGOCD_APP_PARAMETERS=%s", paramsJson)) } + +func getApplicationSpec() *ApplicationSpec { + return &ApplicationSpec{ + Source: &ApplicationSource{ + Path: "source", + }, Sources: ApplicationSources{ + { + Path: "sources/source1", + }, { + Path: "sources/source2", + }, + }, + } +} + +func TestGetSource(t *testing.T) { + tests := []struct { + name string + hasSources bool + hasSource bool + appSpec *ApplicationSpec + expectedSource ApplicationSource + }{ + {"GetSource with Source and Sources field present", true, true, getApplicationSpec(), ApplicationSource{Path: "sources/source1"}}, + {"GetSource with only Sources field", true, false, getApplicationSpec(), ApplicationSource{Path: "sources/source1"}}, + {"GetSource with only Source field", false, true, getApplicationSpec(), ApplicationSource{Path: "source"}}, + {"GetSource with no Source and Sources field", false, false, getApplicationSpec(), ApplicationSource{}}, + } + for _, testCase := range tests { + testCopy := testCase + t.Run(testCopy.name, func(t *testing.T) { + t.Parallel() + if !testCopy.hasSources { + testCopy.appSpec.Sources = nil + } + if !testCopy.hasSource { + testCopy.appSpec.Source = nil + } + source := testCopy.appSpec.GetSource() + assert.Equal(t, testCopy.expectedSource, source) + }) + } +} + +func TestGetSources(t *testing.T) { + tests := []struct { + name string + hasSources bool + hasSource bool + appSpec *ApplicationSpec + expectedSources ApplicationSources + }{ + {"GetSources with Source and Sources field present", true, true, getApplicationSpec(), ApplicationSources{ + {Path: "sources/source1"}, + {Path: "sources/source2"}, + }}, + {"GetSources with only Sources field", true, false, getApplicationSpec(), ApplicationSources{ + {Path: "sources/source1"}, + {Path: "sources/source2"}, + }}, + {"GetSources with only Source field", false, true, getApplicationSpec(), ApplicationSources{ + {Path: "source"}, + }}, + {"GetSources with no Source and Sources field", false, false, getApplicationSpec(), ApplicationSources{}}, + } + for _, testCase := range tests { + testCopy := testCase + t.Run(testCopy.name, func(t *testing.T) { + t.Parallel() + if !testCopy.hasSources { + testCopy.appSpec.Sources = nil + } + if !testCopy.hasSource { + testCopy.appSpec.Source = nil + } + sources := testCopy.appSpec.GetSources() + assert.Equal(t, testCopy.expectedSources, sources) + }) + } +} diff --git a/pkg/apis/application/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/application/v1alpha1/zz_generated.deepcopy.go index e531a4715b0f2..3784e1febe465 100644 --- a/pkg/apis/application/v1alpha1/zz_generated.deepcopy.go +++ b/pkg/apis/application/v1alpha1/zz_generated.deepcopy.go @@ -946,10 +946,36 @@ func (in ApplicationSourcePluginParameters) DeepCopy() ApplicationSourcePluginPa return *out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in ApplicationSources) DeepCopyInto(out *ApplicationSources) { + { + in := &in + *out = make(ApplicationSources, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + return + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ApplicationSources. +func (in ApplicationSources) DeepCopy() ApplicationSources { + if in == nil { + return nil + } + out := new(ApplicationSources) + in.DeepCopyInto(out) + return *out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ApplicationSpec) DeepCopyInto(out *ApplicationSpec) { *out = *in - in.Source.DeepCopyInto(&out.Source) + if in.Source != nil { + in, out := &in.Source, &out.Source + *out = new(ApplicationSource) + (*in).DeepCopyInto(*out) + } out.Destination = in.Destination if in.SyncPolicy != nil { in, out := &in.SyncPolicy, &out.SyncPolicy @@ -973,6 +999,13 @@ func (in *ApplicationSpec) DeepCopyInto(out *ApplicationSpec) { *out = new(int64) **out = **in } + if in.Sources != nil { + in, out := &in.Sources, &out.Sources + *out = make(ApplicationSources, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } return } @@ -1026,6 +1059,11 @@ func (in *ApplicationStatus) DeepCopyInto(out *ApplicationStatus) { *out = (*in).DeepCopy() } in.Summary.DeepCopyInto(&out.Summary) + if in.SourceTypes != nil { + in, out := &in.SourceTypes, &out.SourceTypes + *out = make([]ApplicationSourceType, len(*in)) + copy(*out, *in) + } return } @@ -1358,6 +1396,13 @@ func (in *ComparedTo) DeepCopyInto(out *ComparedTo) { *out = *in in.Source.DeepCopyInto(&out.Source) out.Destination = in.Destination + if in.Sources != nil { + in, out := &in.Sources, &out.Sources + *out = make(ApplicationSources, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } return } @@ -2378,6 +2423,53 @@ func (in *PullRequestGeneratorGithub) DeepCopy() *PullRequestGeneratorGithub { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RefTarget) DeepCopyInto(out *RefTarget) { + *out = *in + in.Repo.DeepCopyInto(&out.Repo) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RefTarget. +func (in *RefTarget) DeepCopy() *RefTarget { + if in == nil { + return nil + } + out := new(RefTarget) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in RefTargetRevisionMapping) DeepCopyInto(out *RefTargetRevisionMapping) { + { + in := &in + *out = make(RefTargetRevisionMapping, len(*in)) + for key, val := range *in { + var outVal *RefTarget + if val == nil { + (*out)[key] = nil + } else { + in, out := &val, &outVal + *out = new(RefTarget) + (*in).DeepCopyInto(*out) + } + (*out)[key] = outVal + } + return + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RefTargetRevisionMapping. +func (in RefTargetRevisionMapping) DeepCopy() RefTargetRevisionMapping { + if in == nil { + return nil + } + out := new(RefTargetRevisionMapping) + in.DeepCopyInto(out) + return *out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *RepoCreds) DeepCopyInto(out *RepoCreds) { *out = *in @@ -2899,6 +2991,18 @@ func (in *RevisionHistory) DeepCopyInto(out *RevisionHistory) { in, out := &in.DeployStartedAt, &out.DeployStartedAt *out = (*in).DeepCopy() } + if in.Sources != nil { + in, out := &in.Sources, &out.Sources + *out = make(ApplicationSources, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.Revisions != nil { + in, out := &in.Revisions, &out.Revisions + *out = make([]string, len(*in)) + copy(*out, *in) + } return } @@ -3220,6 +3324,18 @@ func (in *SyncOperation) DeepCopyInto(out *SyncOperation) { *out = make(SyncOptions, len(*in)) copy(*out, *in) } + if in.Sources != nil { + in, out := &in.Sources, &out.Sources + *out = make(ApplicationSources, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.Revisions != nil { + in, out := &in.Revisions, &out.Revisions + *out = make([]string, len(*in)) + copy(*out, *in) + } return } @@ -3264,6 +3380,18 @@ func (in *SyncOperationResult) DeepCopyInto(out *SyncOperationResult) { } } in.Source.DeepCopyInto(&out.Source) + if in.Sources != nil { + in, out := &in.Sources, &out.Sources + *out = make(ApplicationSources, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.Revisions != nil { + in, out := &in.Revisions, &out.Revisions + *out = make([]string, len(*in)) + copy(*out, *in) + } return } @@ -3353,6 +3481,11 @@ func (in *SyncPolicyAutomated) DeepCopy() *SyncPolicyAutomated { func (in *SyncStatus) DeepCopyInto(out *SyncStatus) { *out = *in in.ComparedTo.DeepCopyInto(&out.ComparedTo) + if in.Revisions != nil { + in, out := &in.Revisions, &out.Revisions + *out = make([]string, len(*in)) + copy(*out, *in) + } return } diff --git a/reposerver/apiclient/mocks/RepoServerServiceClient.go b/reposerver/apiclient/mocks/RepoServerServiceClient.go index fa8a8f295a2fe..8c6dcfaee2b72 100644 --- a/reposerver/apiclient/mocks/RepoServerServiceClient.go +++ b/reposerver/apiclient/mocks/RepoServerServiceClient.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.14.0. DO NOT EDIT. +// Code generated by mockery v2.14.1. DO NOT EDIT. package mocks diff --git a/reposerver/apiclient/repository.pb.go b/reposerver/apiclient/repository.pb.go index 83f0a12ae8bfa..f19807676943c 100644 --- a/reposerver/apiclient/repository.pb.go +++ b/reposerver/apiclient/repository.pb.go @@ -45,15 +45,17 @@ type ManifestRequest struct { KubeVersion string `protobuf:"bytes,14,opt,name=kubeVersion,proto3" json:"kubeVersion,omitempty"` ApiVersions []string `protobuf:"bytes,15,rep,name=apiVersions,proto3" json:"apiVersions,omitempty"` // Request to verify the signature when generating the manifests (only for Git repositories) - VerifySignature bool `protobuf:"varint,16,opt,name=verifySignature,proto3" json:"verifySignature,omitempty"` - HelmRepoCreds []*v1alpha1.RepoCreds `protobuf:"bytes,17,rep,name=helmRepoCreds,proto3" json:"helmRepoCreds,omitempty"` - NoRevisionCache bool `protobuf:"varint,18,opt,name=noRevisionCache,proto3" json:"noRevisionCache,omitempty"` - TrackingMethod string `protobuf:"bytes,19,opt,name=trackingMethod,proto3" json:"trackingMethod,omitempty"` - EnabledSourceTypes map[string]bool `protobuf:"bytes,20,rep,name=enabledSourceTypes,proto3" json:"enabledSourceTypes,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"` - HelmOptions *v1alpha1.HelmOptions `protobuf:"bytes,21,opt,name=helmOptions,proto3" json:"helmOptions,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + VerifySignature bool `protobuf:"varint,16,opt,name=verifySignature,proto3" json:"verifySignature,omitempty"` + HelmRepoCreds []*v1alpha1.RepoCreds `protobuf:"bytes,17,rep,name=helmRepoCreds,proto3" json:"helmRepoCreds,omitempty"` + NoRevisionCache bool `protobuf:"varint,18,opt,name=noRevisionCache,proto3" json:"noRevisionCache,omitempty"` + TrackingMethod string `protobuf:"bytes,19,opt,name=trackingMethod,proto3" json:"trackingMethod,omitempty"` + EnabledSourceTypes map[string]bool `protobuf:"bytes,20,rep,name=enabledSourceTypes,proto3" json:"enabledSourceTypes,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"` + HelmOptions *v1alpha1.HelmOptions `protobuf:"bytes,21,opt,name=helmOptions,proto3" json:"helmOptions,omitempty"` + HasMultipleSources bool `protobuf:"varint,22,opt,name=hasMultipleSources,proto3" json:"hasMultipleSources,omitempty"` + RefSources map[string]*v1alpha1.RefTarget `protobuf:"bytes,23,rep,name=refSources,proto3" json:"refSources,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *ManifestRequest) Reset() { *m = ManifestRequest{} } @@ -215,6 +217,20 @@ func (m *ManifestRequest) GetHelmOptions() *v1alpha1.HelmOptions { return nil } +func (m *ManifestRequest) GetHasMultipleSources() bool { + if m != nil { + return m.HasMultipleSources + } + return false +} + +func (m *ManifestRequest) GetRefSources() map[string]*v1alpha1.RefTarget { + if m != nil { + return m.RefSources + } + return nil +} + type ManifestRequestWithFiles struct { // Types that are valid to be assigned to Part: // *ManifestRequestWithFiles_Request @@ -1039,19 +1055,20 @@ func (m *PluginList) GetItems() []*PluginInfo { // RepoServerAppDetailsQuery contains query information for app details request type RepoServerAppDetailsQuery struct { - Repo *v1alpha1.Repository `protobuf:"bytes,1,opt,name=repo,proto3" json:"repo,omitempty"` - Source *v1alpha1.ApplicationSource `protobuf:"bytes,2,opt,name=source,proto3" json:"source,omitempty"` - Repos []*v1alpha1.Repository `protobuf:"bytes,3,rep,name=repos,proto3" json:"repos,omitempty"` - KustomizeOptions *v1alpha1.KustomizeOptions `protobuf:"bytes,4,opt,name=kustomizeOptions,proto3" json:"kustomizeOptions,omitempty"` - AppName string `protobuf:"bytes,5,opt,name=appName,proto3" json:"appName,omitempty"` - NoCache bool `protobuf:"varint,6,opt,name=noCache,proto3" json:"noCache,omitempty"` - NoRevisionCache bool `protobuf:"varint,7,opt,name=noRevisionCache,proto3" json:"noRevisionCache,omitempty"` - TrackingMethod string `protobuf:"bytes,8,opt,name=trackingMethod,proto3" json:"trackingMethod,omitempty"` - EnabledSourceTypes map[string]bool `protobuf:"bytes,9,rep,name=enabledSourceTypes,proto3" json:"enabledSourceTypes,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"` - HelmOptions *v1alpha1.HelmOptions `protobuf:"bytes,10,opt,name=helmOptions,proto3" json:"helmOptions,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + Repo *v1alpha1.Repository `protobuf:"bytes,1,opt,name=repo,proto3" json:"repo,omitempty"` + Source *v1alpha1.ApplicationSource `protobuf:"bytes,2,opt,name=source,proto3" json:"source,omitempty"` + Repos []*v1alpha1.Repository `protobuf:"bytes,3,rep,name=repos,proto3" json:"repos,omitempty"` + KustomizeOptions *v1alpha1.KustomizeOptions `protobuf:"bytes,4,opt,name=kustomizeOptions,proto3" json:"kustomizeOptions,omitempty"` + AppName string `protobuf:"bytes,5,opt,name=appName,proto3" json:"appName,omitempty"` + NoCache bool `protobuf:"varint,6,opt,name=noCache,proto3" json:"noCache,omitempty"` + NoRevisionCache bool `protobuf:"varint,7,opt,name=noRevisionCache,proto3" json:"noRevisionCache,omitempty"` + TrackingMethod string `protobuf:"bytes,8,opt,name=trackingMethod,proto3" json:"trackingMethod,omitempty"` + EnabledSourceTypes map[string]bool `protobuf:"bytes,9,rep,name=enabledSourceTypes,proto3" json:"enabledSourceTypes,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"` + HelmOptions *v1alpha1.HelmOptions `protobuf:"bytes,10,opt,name=helmOptions,proto3" json:"helmOptions,omitempty"` + RefSources map[string]*v1alpha1.RefTarget `protobuf:"bytes,11,rep,name=refSources,proto3" json:"refSources,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *RepoServerAppDetailsQuery) Reset() { *m = RepoServerAppDetailsQuery{} } @@ -1157,6 +1174,13 @@ func (m *RepoServerAppDetailsQuery) GetHelmOptions() *v1alpha1.HelmOptions { return nil } +func (m *RepoServerAppDetailsQuery) GetRefSources() map[string]*v1alpha1.RefTarget { + if m != nil { + return m.RefSources + } + return nil +} + // RepoAppDetailsResponse application details type RepoAppDetailsResponse struct { Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"` @@ -1798,6 +1822,7 @@ func (m *HelmChartsResponse) GetItems() []*HelmChart { func init() { proto.RegisterType((*ManifestRequest)(nil), "repository.ManifestRequest") proto.RegisterMapType((map[string]bool)(nil), "repository.ManifestRequest.EnabledSourceTypesEntry") + proto.RegisterMapType((map[string]*v1alpha1.RefTarget)(nil), "repository.ManifestRequest.RefSourcesEntry") proto.RegisterType((*ManifestRequestWithFiles)(nil), "repository.ManifestRequestWithFiles") proto.RegisterType((*ManifestFileMetadata)(nil), "repository.ManifestFileMetadata") proto.RegisterType((*ManifestFileChunk)(nil), "repository.ManifestFileChunk") @@ -1816,6 +1841,7 @@ func init() { proto.RegisterType((*PluginList)(nil), "repository.PluginList") proto.RegisterType((*RepoServerAppDetailsQuery)(nil), "repository.RepoServerAppDetailsQuery") proto.RegisterMapType((map[string]bool)(nil), "repository.RepoServerAppDetailsQuery.EnabledSourceTypesEntry") + proto.RegisterMapType((map[string]*v1alpha1.RefTarget)(nil), "repository.RepoServerAppDetailsQuery.RefSourcesEntry") proto.RegisterType((*RepoAppDetailsResponse)(nil), "repository.RepoAppDetailsResponse") proto.RegisterType((*RepoServerRevisionMetadataRequest)(nil), "repository.RepoServerRevisionMetadataRequest") proto.RegisterType((*HelmAppSpec)(nil), "repository.HelmAppSpec") @@ -1834,120 +1860,124 @@ func init() { } var fileDescriptor_dd8723cfcc820480 = []byte{ - // 1797 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x59, 0x4b, 0x6f, 0x1b, 0xc9, - 0x11, 0x16, 0x1f, 0xa2, 0xc8, 0xa2, 0x2d, 0x51, 0x6d, 0x5b, 0x1e, 0x73, 0xbd, 0x02, 0x77, 0x92, - 0x18, 0xca, 0x3e, 0x86, 0xb0, 0x8c, 0xec, 0x06, 0xde, 0x64, 0x03, 0xae, 0xd6, 0xb6, 0x0c, 0x5b, - 0xb6, 0x32, 0x36, 0x12, 0x6c, 0x62, 0x24, 0x68, 0x0e, 0x9b, 0xc3, 0x5e, 0xce, 0xa3, 0x3d, 0xd3, - 0xc3, 0x80, 0x06, 0x72, 0x08, 0x90, 0x4b, 0xae, 0x39, 0xe4, 0xaf, 0xe4, 0x98, 0x53, 0x82, 0x1c, - 0x83, 0xfc, 0x81, 0x04, 0xbe, 0xe4, 0x6f, 0x04, 0xdd, 0xd3, 0xf3, 0xe0, 0x70, 0x28, 0xef, 0x82, - 0x5a, 0x19, 0x7b, 0x91, 0xba, 0xaa, 0xab, 0xab, 0xaa, 0x6b, 0xaa, 0xab, 0xbe, 0x6e, 0xc2, 0xad, - 0x80, 0x30, 0x3f, 0x24, 0xc1, 0x8c, 0x04, 0x7d, 0x39, 0xa4, 0xdc, 0x0f, 0xe6, 0xb9, 0xa1, 0xc1, - 0x02, 0x9f, 0xfb, 0x08, 0x32, 0x4e, 0xf7, 0xb1, 0x4d, 0xf9, 0x24, 0x1a, 0x1a, 0x96, 0xef, 0xf6, - 0x71, 0x60, 0xfb, 0x2c, 0xf0, 0xbf, 0x92, 0x83, 0x8f, 0xac, 0x51, 0x7f, 0x76, 0xd8, 0x67, 0x53, - 0xbb, 0x8f, 0x19, 0x0d, 0xfb, 0x98, 0x31, 0x87, 0x5a, 0x98, 0x53, 0xdf, 0xeb, 0xcf, 0x6e, 0x63, - 0x87, 0x4d, 0xf0, 0xed, 0xbe, 0x4d, 0x3c, 0x12, 0x60, 0x4e, 0x46, 0xb1, 0xe6, 0xee, 0x3b, 0xb6, - 0xef, 0xdb, 0x0e, 0xe9, 0x4b, 0x6a, 0x18, 0x8d, 0xfb, 0xc4, 0x65, 0x5c, 0x99, 0xd5, 0xff, 0x0c, - 0xb0, 0x73, 0x82, 0x3d, 0x3a, 0x26, 0x21, 0x37, 0xc9, 0xcb, 0x88, 0x84, 0x1c, 0xbd, 0x80, 0xba, - 0x70, 0x46, 0xab, 0xf4, 0x2a, 0x07, 0xed, 0xc3, 0x63, 0x23, 0xf3, 0xc6, 0x48, 0xbc, 0x91, 0x83, - 0xdf, 0x5a, 0x23, 0x63, 0x76, 0x68, 0xb0, 0xa9, 0x6d, 0x08, 0x6f, 0x8c, 0x9c, 0x37, 0x46, 0xe2, - 0x8d, 0x61, 0xa6, 0xdb, 0x32, 0xa5, 0x56, 0xd4, 0x85, 0x66, 0x40, 0x66, 0x34, 0xa4, 0xbe, 0xa7, - 0x55, 0x7b, 0x95, 0x83, 0x96, 0x99, 0xd2, 0x48, 0x83, 0x2d, 0xcf, 0x3f, 0xc2, 0xd6, 0x84, 0x68, - 0xb5, 0x5e, 0xe5, 0xa0, 0x69, 0x26, 0x24, 0xea, 0x41, 0x1b, 0x33, 0xf6, 0x18, 0x0f, 0x89, 0xf3, - 0x88, 0xcc, 0xb5, 0xba, 0x5c, 0x98, 0x67, 0x89, 0xb5, 0x98, 0xb1, 0x27, 0xd8, 0x25, 0xda, 0xa6, - 0x9c, 0x4d, 0x48, 0x74, 0x13, 0x5a, 0x1e, 0x76, 0x49, 0xc8, 0xb0, 0x45, 0xb4, 0xa6, 0x9c, 0xcb, - 0x18, 0xe8, 0xf7, 0xb0, 0x9b, 0x73, 0xfc, 0x99, 0x1f, 0x05, 0x16, 0xd1, 0x40, 0x6e, 0xfd, 0xe9, - 0x7a, 0x5b, 0x1f, 0x14, 0xd5, 0x9a, 0xcb, 0x96, 0xd0, 0x6f, 0x60, 0x53, 0x7e, 0x79, 0xad, 0xdd, - 0xab, 0x9d, 0x6b, 0xb4, 0x63, 0xb5, 0xc8, 0x83, 0x2d, 0xe6, 0x44, 0x36, 0xf5, 0x42, 0xed, 0x92, - 0xb4, 0xf0, 0x7c, 0x3d, 0x0b, 0x47, 0xbe, 0x37, 0xa6, 0xf6, 0x09, 0xf6, 0xb0, 0x4d, 0x5c, 0xe2, - 0xf1, 0x53, 0xa9, 0xdc, 0x4c, 0x8c, 0xa0, 0x57, 0xd0, 0x99, 0x46, 0x21, 0xf7, 0x5d, 0xfa, 0x8a, - 0x3c, 0x65, 0x62, 0x6d, 0xa8, 0x5d, 0x96, 0xd1, 0x7c, 0xb2, 0x9e, 0xe1, 0x47, 0x05, 0xad, 0xe6, - 0x92, 0x1d, 0x91, 0x24, 0xd3, 0x68, 0x48, 0x7e, 0x41, 0x02, 0x99, 0x5d, 0xdb, 0x71, 0x92, 0xe4, - 0x58, 0x71, 0x1a, 0x51, 0x45, 0x85, 0xda, 0x4e, 0xaf, 0x16, 0xa7, 0x51, 0xca, 0x42, 0x07, 0xb0, - 0x33, 0x23, 0x01, 0x1d, 0xcf, 0x9f, 0x51, 0xdb, 0xc3, 0x3c, 0x0a, 0x88, 0xd6, 0x91, 0xa9, 0x58, - 0x64, 0x23, 0x17, 0x2e, 0x4f, 0x88, 0xe3, 0x8a, 0x90, 0x1f, 0x05, 0x64, 0x14, 0x6a, 0xbb, 0x32, - 0xbe, 0x0f, 0xd6, 0xff, 0x82, 0x52, 0x9d, 0xb9, 0xa8, 0x5d, 0x38, 0xe6, 0xf9, 0xa6, 0x3a, 0x29, - 0xf1, 0x19, 0x41, 0xb1, 0x63, 0x05, 0x36, 0xba, 0x05, 0xdb, 0x3c, 0xc0, 0xd6, 0x94, 0x7a, 0xf6, - 0x09, 0xe1, 0x13, 0x7f, 0xa4, 0x5d, 0x91, 0x91, 0x28, 0x70, 0x91, 0x05, 0x88, 0x78, 0x78, 0xe8, - 0x90, 0x51, 0x9c, 0x8b, 0xcf, 0xe7, 0x8c, 0x84, 0xda, 0x55, 0xb9, 0x8b, 0x3b, 0x46, 0xae, 0x42, - 0x15, 0x0a, 0x84, 0x71, 0x6f, 0x69, 0xd5, 0x3d, 0x8f, 0x07, 0x73, 0xb3, 0x44, 0x1d, 0x9a, 0x42, - 0x5b, 0xec, 0x23, 0x49, 0x85, 0x6b, 0x32, 0x15, 0x1e, 0xae, 0x17, 0xa3, 0xe3, 0x4c, 0xa1, 0x99, - 0xd7, 0xde, 0xbd, 0x07, 0xd7, 0x57, 0xf8, 0x86, 0x3a, 0x50, 0x9b, 0x92, 0xb9, 0xac, 0x69, 0x2d, - 0x53, 0x0c, 0xd1, 0x55, 0xd8, 0x9c, 0x61, 0x27, 0x22, 0xb2, 0x0a, 0x35, 0xcd, 0x98, 0xb8, 0x5b, - 0xfd, 0x71, 0x45, 0xff, 0x77, 0x05, 0xb4, 0xc2, 0x9e, 0x7f, 0x49, 0xf9, 0xe4, 0x3e, 0x75, 0x48, - 0x88, 0x3e, 0x81, 0xad, 0x20, 0xe6, 0xa9, 0x02, 0xf9, 0xce, 0x19, 0xa1, 0x3a, 0xde, 0x30, 0x13, - 0x69, 0xf4, 0x19, 0x34, 0x5d, 0xc2, 0xf1, 0x08, 0x73, 0x2c, 0x4d, 0xb6, 0x0f, 0x7b, 0x65, 0x2b, - 0x85, 0x95, 0x13, 0x25, 0x77, 0xbc, 0x61, 0xa6, 0x6b, 0xd0, 0x8f, 0x60, 0xd3, 0x9a, 0x44, 0xde, - 0x54, 0x96, 0xc6, 0xf6, 0xe1, 0xbb, 0xab, 0x16, 0x1f, 0x09, 0xa1, 0xe3, 0x0d, 0x33, 0x96, 0xfe, - 0xbc, 0x01, 0x75, 0x86, 0x03, 0xae, 0xdf, 0x87, 0xab, 0x65, 0x26, 0x44, 0x3d, 0xb6, 0x26, 0xc4, - 0x9a, 0x86, 0x91, 0xab, 0xa2, 0x93, 0xd2, 0x08, 0x41, 0x3d, 0xa4, 0xaf, 0xe2, 0x08, 0xd5, 0x4c, - 0x39, 0xd6, 0x7f, 0x08, 0xbb, 0x4b, 0xd6, 0x44, 0x2c, 0x63, 0xdf, 0x84, 0x86, 0x4b, 0xca, 0xb4, - 0x1e, 0xc1, 0xb5, 0xe7, 0x32, 0x16, 0x69, 0x51, 0xba, 0x88, 0x0e, 0xa3, 0x1f, 0xc3, 0x5e, 0xd1, - 0x6c, 0xc8, 0x7c, 0x2f, 0x24, 0xc8, 0x00, 0x24, 0x4f, 0x31, 0x25, 0xa3, 0x6c, 0x56, 0x7a, 0xd1, - 0x34, 0x4b, 0x66, 0xf4, 0x3f, 0x54, 0x61, 0xcf, 0x24, 0xa1, 0xef, 0xcc, 0x48, 0x72, 0xc4, 0x2e, - 0xa6, 0x49, 0xfe, 0x1a, 0x6a, 0x98, 0x31, 0x95, 0x26, 0x0f, 0xcf, 0xad, 0x0d, 0x99, 0x42, 0x2b, - 0xfa, 0x10, 0x76, 0xb1, 0x3b, 0xa4, 0x76, 0xe4, 0x47, 0x61, 0xb2, 0x2d, 0x99, 0x54, 0x2d, 0x73, - 0x79, 0x42, 0xb7, 0xe0, 0xfa, 0x52, 0x08, 0x54, 0x38, 0xf3, 0xad, 0xbc, 0x52, 0x68, 0xe5, 0xa5, - 0x46, 0xaa, 0xab, 0x8c, 0xfc, 0xa3, 0x02, 0x9d, 0xec, 0xe8, 0x28, 0xf5, 0x37, 0xa1, 0xe5, 0x2a, - 0x5e, 0xa8, 0x55, 0x64, 0xa9, 0xce, 0x18, 0x8b, 0x5d, 0xbd, 0x5a, 0xec, 0xea, 0x7b, 0xd0, 0x88, - 0x41, 0x97, 0xda, 0x98, 0xa2, 0x16, 0x5c, 0xae, 0x17, 0x5c, 0xde, 0x07, 0x08, 0xd3, 0xb2, 0xa1, - 0x35, 0xe4, 0x6c, 0x8e, 0x83, 0x74, 0xb8, 0x14, 0xf7, 0x00, 0x93, 0x84, 0x91, 0xc3, 0xb5, 0x2d, - 0x29, 0xb1, 0xc0, 0xd3, 0x7d, 0xd8, 0x79, 0x4c, 0xc5, 0x1e, 0xc6, 0xe1, 0xc5, 0x24, 0xfb, 0xc7, - 0x50, 0x17, 0xc6, 0xc4, 0xc6, 0x86, 0x01, 0xf6, 0xac, 0x09, 0x49, 0x62, 0x95, 0xd2, 0xe2, 0x18, - 0x73, 0x6c, 0x87, 0x5a, 0x55, 0xf2, 0xe5, 0x58, 0xff, 0x6b, 0x35, 0xf6, 0x74, 0xc0, 0x58, 0xf8, - 0xf6, 0x81, 0x5f, 0x79, 0x2b, 0xaa, 0x2d, 0xb7, 0xa2, 0x82, 0xcb, 0xdf, 0xa4, 0x15, 0x9d, 0x57, - 0x77, 0x88, 0x60, 0x6b, 0xc0, 0x98, 0x70, 0x04, 0xdd, 0x86, 0x3a, 0x66, 0x2c, 0x0e, 0x78, 0xa1, - 0x22, 0x2b, 0x11, 0xf1, 0x5f, 0xb9, 0x24, 0x45, 0xbb, 0x9f, 0x40, 0x2b, 0x65, 0xbd, 0xc9, 0x6c, - 0x2b, 0x6f, 0xb6, 0x07, 0x10, 0x63, 0xad, 0x87, 0xde, 0xd8, 0x17, 0x9f, 0x54, 0x24, 0xbb, 0x5a, - 0x2a, 0xc7, 0xfa, 0xdd, 0x44, 0x42, 0xfa, 0xf6, 0x21, 0x6c, 0x52, 0x4e, 0xdc, 0xc4, 0xb9, 0xbd, - 0xbc, 0x73, 0x99, 0x22, 0x33, 0x16, 0xd2, 0xff, 0xd7, 0x80, 0x1b, 0xe2, 0x8b, 0x3d, 0x93, 0xc7, - 0x64, 0xc0, 0xd8, 0x17, 0x84, 0x63, 0xea, 0x84, 0x3f, 0x8f, 0x48, 0x30, 0xff, 0x96, 0x13, 0xc3, - 0x86, 0x46, 0x7c, 0xca, 0x54, 0xbd, 0x3b, 0x77, 0xd8, 0xad, 0xd4, 0x67, 0x58, 0xbb, 0xf6, 0xed, - 0x60, 0xed, 0x32, 0xec, 0x5b, 0xbf, 0x20, 0xec, 0xbb, 0xfa, 0xfa, 0x93, 0xbb, 0x54, 0x35, 0x16, - 0x2f, 0x55, 0x25, 0x90, 0x72, 0xeb, 0xeb, 0x42, 0xca, 0x66, 0x29, 0xa4, 0x74, 0x4b, 0xcf, 0x71, - 0x4b, 0x86, 0xfb, 0xa7, 0xf9, 0x0c, 0x5c, 0x99, 0x6b, 0xeb, 0x80, 0x4b, 0xf8, 0x2e, 0x80, 0xcb, - 0x3f, 0x4a, 0x4c, 0xc1, 0xfc, 0x6c, 0xdf, 0x69, 0xc3, 0x13, 0x75, 0x5a, 0xb4, 0x1e, 0x75, 0xa8, - 0xc5, 0x18, 0x7d, 0x00, 0x75, 0xe1, 0x84, 0x02, 0x7d, 0xd7, 0xf3, 0x31, 0x14, 0x9e, 0x0e, 0x18, - 0x7b, 0xc6, 0x88, 0x65, 0x4a, 0x21, 0x74, 0x17, 0x5a, 0x69, 0x62, 0xa8, 0xcc, 0xbb, 0x99, 0x5f, - 0x91, 0xe6, 0x51, 0xb2, 0x2c, 0x13, 0x17, 0x6b, 0x47, 0x34, 0x20, 0x96, 0x84, 0x44, 0x9b, 0xcb, - 0x6b, 0xbf, 0x48, 0x26, 0xd3, 0xb5, 0xa9, 0x38, 0xba, 0x0d, 0x8d, 0xf8, 0xfe, 0x27, 0x33, 0xac, - 0x7d, 0x78, 0x63, 0xb9, 0xd8, 0x24, 0xab, 0x94, 0xa0, 0xfe, 0xf7, 0x0a, 0xbc, 0x97, 0x25, 0x41, - 0x92, 0x6d, 0x09, 0x2a, 0x7d, 0xfb, 0x1d, 0xe9, 0x16, 0x6c, 0x4b, 0x18, 0x9c, 0x5d, 0x03, 0xe3, - 0x17, 0x89, 0x02, 0x57, 0xff, 0x5b, 0x15, 0xda, 0xb9, 0x0f, 0x51, 0x56, 0x98, 0x05, 0xb0, 0x90, - 0xdf, 0x5f, 0x5e, 0x20, 0x64, 0xf1, 0x69, 0x99, 0x39, 0x0e, 0x9a, 0x02, 0x30, 0x1c, 0x60, 0x97, - 0x70, 0x12, 0x88, 0x8a, 0x21, 0x4e, 0xcb, 0xa3, 0xf5, 0xb3, 0xf8, 0x34, 0xd1, 0x69, 0xe6, 0xd4, - 0x0b, 0x64, 0x24, 0x4d, 0x87, 0xaa, 0x4e, 0x28, 0x0a, 0xfd, 0x0e, 0xb6, 0xc7, 0xd4, 0x21, 0xa7, - 0x99, 0x23, 0x0d, 0xe9, 0xc8, 0xd3, 0xf5, 0x1d, 0xb9, 0x9f, 0xd7, 0x6b, 0x16, 0xcc, 0xe8, 0xef, - 0x43, 0xa7, 0x98, 0x97, 0xc2, 0x49, 0xea, 0x62, 0x3b, 0x8d, 0x96, 0xa2, 0x74, 0x04, 0x9d, 0x62, - 0x1e, 0xea, 0xff, 0xa9, 0xc2, 0xb5, 0x54, 0xdd, 0xc0, 0xf3, 0xfc, 0xc8, 0xb3, 0xe4, 0xd3, 0x44, - 0xe9, 0xb7, 0xb8, 0x0a, 0x9b, 0x9c, 0x72, 0x27, 0x6d, 0xb0, 0x92, 0x10, 0x35, 0x92, 0xfb, 0xbe, - 0xc3, 0x29, 0x53, 0x78, 0x31, 0x21, 0xe3, 0x1c, 0x79, 0x19, 0xd1, 0x80, 0x8c, 0xe4, 0x89, 0x6a, - 0x9a, 0x29, 0x2d, 0xe6, 0x44, 0xf7, 0x94, 0x70, 0x31, 0x0e, 0x66, 0x4a, 0xcb, 0xfc, 0xf1, 0x1d, - 0x87, 0x58, 0x22, 0x1c, 0x39, 0x40, 0x59, 0xe0, 0x4a, 0xa0, 0xca, 0x03, 0xea, 0xd9, 0x0a, 0x4e, - 0x2a, 0x4a, 0xf8, 0x89, 0x83, 0x00, 0xcf, 0xb5, 0xa6, 0x0c, 0x40, 0x4c, 0xa0, 0x9f, 0x40, 0xcd, - 0xc5, 0x4c, 0x15, 0xd4, 0xf7, 0x17, 0x4e, 0x59, 0x59, 0x04, 0x8c, 0x13, 0xcc, 0xe2, 0xea, 0x29, - 0x96, 0x75, 0x3f, 0x86, 0x66, 0xc2, 0xf8, 0x46, 0xd0, 0xe3, 0x2b, 0xb8, 0xbc, 0x70, 0x88, 0xd1, - 0x97, 0xb0, 0x97, 0x65, 0x54, 0xde, 0xa0, 0x02, 0x1b, 0xef, 0xbd, 0xd1, 0x33, 0x73, 0x85, 0x02, - 0xfd, 0x25, 0xec, 0x8a, 0x94, 0x39, 0x9a, 0xe0, 0x80, 0x5f, 0x10, 0x84, 0xfe, 0x14, 0x5a, 0xa9, - 0xc9, 0xd2, 0x9c, 0xe9, 0x42, 0x73, 0x96, 0x3c, 0x19, 0xc5, 0x18, 0x3a, 0xa5, 0xf5, 0x01, 0xa0, - 0xbc, 0xbf, 0xaa, 0x92, 0x7f, 0xb0, 0x08, 0xbe, 0xae, 0x15, 0xcb, 0xb6, 0x14, 0x57, 0xd8, 0xeb, - 0xf0, 0x4f, 0x5b, 0xb0, 0x9b, 0x95, 0x42, 0xf1, 0x97, 0x5a, 0x04, 0x3d, 0x85, 0xce, 0x03, 0xf5, - 0x92, 0x9b, 0xdc, 0x8c, 0xd0, 0x59, 0x4f, 0x0d, 0xdd, 0x9b, 0xe5, 0x93, 0xb1, 0x47, 0xfa, 0x06, - 0xb2, 0xe0, 0x46, 0x51, 0x61, 0xf6, 0xaa, 0xf1, 0xfd, 0x33, 0x34, 0xa7, 0x52, 0x6f, 0x32, 0x71, - 0x50, 0x41, 0x5f, 0xc2, 0xf6, 0xe2, 0xdd, 0x1b, 0x2d, 0xe4, 0x42, 0xe9, 0x73, 0x40, 0x57, 0x3f, - 0x4b, 0x24, 0xf5, 0xff, 0x05, 0xec, 0x14, 0x2e, 0xa2, 0x48, 0x5f, 0x84, 0x14, 0x65, 0x17, 0xf5, - 0xee, 0xf7, 0xce, 0x94, 0x49, 0xb5, 0x7f, 0x0a, 0xcd, 0xe4, 0xe2, 0xb6, 0x18, 0xe6, 0xc2, 0x75, - 0xae, 0xdb, 0x59, 0xd4, 0x37, 0x0e, 0xf5, 0x0d, 0xf4, 0x59, 0xbc, 0x58, 0x00, 0xfb, 0xe5, 0xc5, - 0xb9, 0xeb, 0x4a, 0xf7, 0x4a, 0xc9, 0x15, 0x41, 0xdf, 0x40, 0x3f, 0x83, 0xb6, 0x18, 0x9d, 0xaa, - 0x37, 0xd4, 0x3d, 0x23, 0x7e, 0xb2, 0x37, 0x92, 0x27, 0x7b, 0xe3, 0x9e, 0xcb, 0xf8, 0xbc, 0x5b, - 0x82, 0xe1, 0x95, 0x82, 0x17, 0x70, 0xf9, 0x01, 0xe1, 0x19, 0xa4, 0x40, 0x3f, 0xf8, 0x5a, 0x60, - 0xab, 0xab, 0x17, 0xc5, 0x96, 0x51, 0x89, 0xbe, 0x81, 0xfe, 0x52, 0x81, 0x2b, 0x0f, 0x08, 0x2f, - 0x36, 0x69, 0xf4, 0x51, 0xb9, 0x91, 0x15, 0xcd, 0xbc, 0xfb, 0x64, 0xdd, 0x73, 0xbb, 0xa8, 0x56, - 0xdf, 0x40, 0xa7, 0x72, 0xdb, 0xd9, 0xf9, 0x43, 0xef, 0x96, 0x1e, 0xb4, 0x34, 0xfc, 0xfb, 0xab, - 0xa6, 0x93, 0xad, 0x7e, 0x3e, 0xf8, 0xe7, 0xeb, 0xfd, 0xca, 0xbf, 0x5e, 0xef, 0x57, 0xfe, 0xfb, - 0x7a, 0xbf, 0xf2, 0xab, 0x3b, 0x6f, 0xf8, 0x21, 0x26, 0xf7, 0xdb, 0x0e, 0x66, 0xd4, 0x72, 0x28, - 0xf1, 0xf8, 0xb0, 0x21, 0xbf, 0xda, 0x9d, 0xff, 0x07, 0x00, 0x00, 0xff, 0xff, 0x86, 0x50, 0xb1, - 0xb6, 0xfa, 0x19, 0x00, 0x00, + // 1870 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe4, 0x19, 0xdb, 0x6e, 0x1c, 0x49, + 0xd5, 0x73, 0xb1, 0x3d, 0x73, 0x9c, 0xf8, 0x52, 0x49, 0x9c, 0xce, 0x6c, 0xd6, 0xf2, 0x36, 0x10, + 0x99, 0xcd, 0x6e, 0x8f, 0xe2, 0x68, 0x77, 0x51, 0x16, 0x16, 0x79, 0xbd, 0x49, 0x1c, 0x25, 0x4e, + 0x4c, 0x27, 0x80, 0x16, 0x02, 0xa8, 0xdc, 0x53, 0xd3, 0x53, 0x3b, 0x7d, 0xa9, 0x74, 0x57, 0x0f, + 0x9a, 0x48, 0x3c, 0x20, 0x21, 0x24, 0x7e, 0x00, 0xf1, 0x27, 0x3c, 0xf2, 0xc4, 0xe5, 0x11, 0xf1, + 0x03, 0xa0, 0x7c, 0x09, 0xaa, 0x4b, 0x5f, 0xa7, 0xed, 0x64, 0x35, 0x8e, 0xf7, 0x61, 0x5f, 0xec, + 0xae, 0x53, 0xe7, 0x56, 0xa7, 0xce, 0xb5, 0x06, 0x6e, 0x44, 0x84, 0x85, 0x31, 0x89, 0x26, 0x24, + 0xea, 0xcb, 0x4f, 0xca, 0xc3, 0x68, 0x5a, 0xf8, 0xb4, 0x58, 0x14, 0xf2, 0x10, 0x41, 0x0e, 0xe9, + 0x3d, 0x72, 0x29, 0x1f, 0x25, 0xc7, 0x96, 0x13, 0xfa, 0x7d, 0x1c, 0xb9, 0x21, 0x8b, 0xc2, 0xaf, + 0xe4, 0xc7, 0x87, 0xce, 0xa0, 0x3f, 0xd9, 0xed, 0xb3, 0xb1, 0xdb, 0xc7, 0x8c, 0xc6, 0x7d, 0xcc, + 0x98, 0x47, 0x1d, 0xcc, 0x69, 0x18, 0xf4, 0x27, 0xb7, 0xb0, 0xc7, 0x46, 0xf8, 0x56, 0xdf, 0x25, + 0x01, 0x89, 0x30, 0x27, 0x03, 0xc5, 0xb9, 0xf7, 0x8e, 0x1b, 0x86, 0xae, 0x47, 0xfa, 0x72, 0x75, + 0x9c, 0x0c, 0xfb, 0xc4, 0x67, 0x5c, 0x8b, 0x35, 0xff, 0x72, 0x01, 0xd6, 0x0e, 0x71, 0x40, 0x87, + 0x24, 0xe6, 0x36, 0x79, 0x91, 0x90, 0x98, 0xa3, 0xe7, 0xd0, 0x16, 0xca, 0x18, 0x8d, 0xed, 0xc6, + 0xce, 0xca, 0xee, 0x81, 0x95, 0x6b, 0x63, 0xa5, 0xda, 0xc8, 0x8f, 0xdf, 0x38, 0x03, 0x6b, 0xb2, + 0x6b, 0xb1, 0xb1, 0x6b, 0x09, 0x6d, 0xac, 0x82, 0x36, 0x56, 0xaa, 0x8d, 0x65, 0x67, 0xc7, 0xb2, + 0x25, 0x57, 0xd4, 0x83, 0x4e, 0x44, 0x26, 0x34, 0xa6, 0x61, 0x60, 0x34, 0xb7, 0x1b, 0x3b, 0x5d, + 0x3b, 0x5b, 0x23, 0x03, 0x96, 0x83, 0x70, 0x1f, 0x3b, 0x23, 0x62, 0xb4, 0xb6, 0x1b, 0x3b, 0x1d, + 0x3b, 0x5d, 0xa2, 0x6d, 0x58, 0xc1, 0x8c, 0x3d, 0xc2, 0xc7, 0xc4, 0x7b, 0x48, 0xa6, 0x46, 0x5b, + 0x12, 0x16, 0x41, 0x82, 0x16, 0x33, 0xf6, 0x18, 0xfb, 0xc4, 0x58, 0x94, 0xbb, 0xe9, 0x12, 0x5d, + 0x87, 0x6e, 0x80, 0x7d, 0x12, 0x33, 0xec, 0x10, 0xa3, 0x23, 0xf7, 0x72, 0x00, 0xfa, 0x1d, 0x6c, + 0x14, 0x14, 0x7f, 0x1a, 0x26, 0x91, 0x43, 0x0c, 0x90, 0x47, 0x7f, 0x32, 0xdf, 0xd1, 0xf7, 0xaa, + 0x6c, 0xed, 0x59, 0x49, 0xe8, 0xd7, 0xb0, 0x28, 0x6f, 0xde, 0x58, 0xd9, 0x6e, 0x9d, 0xa9, 0xb5, + 0x15, 0x5b, 0x14, 0xc0, 0x32, 0xf3, 0x12, 0x97, 0x06, 0xb1, 0x71, 0x41, 0x4a, 0x78, 0x36, 0x9f, + 0x84, 0xfd, 0x30, 0x18, 0x52, 0xf7, 0x10, 0x07, 0xd8, 0x25, 0x3e, 0x09, 0xf8, 0x91, 0x64, 0x6e, + 0xa7, 0x42, 0xd0, 0x4b, 0x58, 0x1f, 0x27, 0x31, 0x0f, 0x7d, 0xfa, 0x92, 0x3c, 0x61, 0x82, 0x36, + 0x36, 0x2e, 0x4a, 0x6b, 0x3e, 0x9e, 0x4f, 0xf0, 0xc3, 0x0a, 0x57, 0x7b, 0x46, 0x8e, 0x70, 0x92, + 0x71, 0x72, 0x4c, 0x7e, 0x46, 0x22, 0xe9, 0x5d, 0xab, 0xca, 0x49, 0x0a, 0x20, 0xe5, 0x46, 0x54, + 0xaf, 0x62, 0x63, 0x6d, 0xbb, 0xa5, 0xdc, 0x28, 0x03, 0xa1, 0x1d, 0x58, 0x9b, 0x90, 0x88, 0x0e, + 0xa7, 0x4f, 0xa9, 0x1b, 0x60, 0x9e, 0x44, 0xc4, 0x58, 0x97, 0xae, 0x58, 0x05, 0x23, 0x1f, 0x2e, + 0x8e, 0x88, 0xe7, 0x0b, 0x93, 0xef, 0x47, 0x64, 0x10, 0x1b, 0x1b, 0xd2, 0xbe, 0xf7, 0xe7, 0xbf, + 0x41, 0xc9, 0xce, 0x2e, 0x73, 0x17, 0x8a, 0x05, 0xa1, 0xad, 0x23, 0x45, 0xc5, 0x08, 0x52, 0x8a, + 0x55, 0xc0, 0xe8, 0x06, 0xac, 0xf2, 0x08, 0x3b, 0x63, 0x1a, 0xb8, 0x87, 0x84, 0x8f, 0xc2, 0x81, + 0x71, 0x49, 0x5a, 0xa2, 0x02, 0x45, 0x0e, 0x20, 0x12, 0xe0, 0x63, 0x8f, 0x0c, 0x94, 0x2f, 0x3e, + 0x9b, 0x32, 0x12, 0x1b, 0x97, 0xe5, 0x29, 0x6e, 0x5b, 0x85, 0x0c, 0x55, 0x49, 0x10, 0xd6, 0xdd, + 0x19, 0xaa, 0xbb, 0x01, 0x8f, 0xa6, 0x76, 0x0d, 0x3b, 0x34, 0x86, 0x15, 0x71, 0x8e, 0xd4, 0x15, + 0xae, 0x48, 0x57, 0x78, 0x30, 0x9f, 0x8d, 0x0e, 0x72, 0x86, 0x76, 0x91, 0x3b, 0xb2, 0x00, 0x8d, + 0x70, 0x7c, 0x98, 0x78, 0x9c, 0x32, 0x8f, 0x28, 0x35, 0x62, 0x63, 0x53, 0x9a, 0xa9, 0x66, 0x07, + 0x3d, 0x04, 0x88, 0xc8, 0x30, 0xc5, 0xbb, 0x2a, 0x4f, 0x7e, 0xf3, 0xb4, 0x93, 0xdb, 0x19, 0xb6, + 0x3a, 0x71, 0x81, 0xbc, 0x77, 0x17, 0xae, 0x9e, 0x60, 0x18, 0xb4, 0x0e, 0xad, 0x31, 0x99, 0xca, + 0x84, 0xda, 0xb5, 0xc5, 0x27, 0xba, 0x0c, 0x8b, 0x13, 0xec, 0x25, 0x44, 0xa6, 0xc0, 0x8e, 0xad, + 0x16, 0x77, 0x9a, 0x3f, 0x68, 0xf4, 0xfe, 0xd8, 0x80, 0xb5, 0x8a, 0x98, 0x1a, 0xfa, 0x5f, 0x15, + 0xe9, 0xcf, 0xc0, 0xe9, 0x86, 0xcf, 0x70, 0xe4, 0x12, 0x5e, 0x50, 0xc4, 0xfc, 0x4f, 0x03, 0x8c, + 0xca, 0xf9, 0x7f, 0x4e, 0xf9, 0xe8, 0x1e, 0xf5, 0x48, 0x8c, 0x3e, 0x81, 0xe5, 0x48, 0xc1, 0x74, + 0x99, 0x78, 0xe7, 0x14, 0xb3, 0x1d, 0x2c, 0xd8, 0x29, 0x36, 0xfa, 0x0c, 0x3a, 0x3e, 0xe1, 0x78, + 0x80, 0x39, 0xd6, 0xba, 0x6f, 0xd7, 0x51, 0x0a, 0x29, 0x87, 0x1a, 0xef, 0x60, 0xc1, 0xce, 0x68, + 0xd0, 0x47, 0xb0, 0xe8, 0x8c, 0x92, 0x60, 0x2c, 0x0b, 0xc4, 0xca, 0xee, 0xbb, 0x27, 0x11, 0xef, + 0x0b, 0xa4, 0x83, 0x05, 0x5b, 0x61, 0x7f, 0xbe, 0x04, 0x6d, 0x86, 0x23, 0x6e, 0xde, 0x83, 0xcb, + 0x75, 0x22, 0x44, 0x55, 0x72, 0x46, 0xc4, 0x19, 0xc7, 0x89, 0xaf, 0xcd, 0x9c, 0xad, 0x11, 0x82, + 0x76, 0x4c, 0x5f, 0x2a, 0x53, 0xb7, 0x6c, 0xf9, 0x6d, 0x7e, 0x1f, 0x36, 0x66, 0xa4, 0x89, 0x4b, + 0x55, 0xba, 0x09, 0x0e, 0x17, 0xb4, 0x68, 0x33, 0x81, 0x2b, 0xcf, 0xa4, 0x2d, 0xb2, 0xd4, 0x7c, + 0x1e, 0x75, 0xd6, 0x3c, 0x80, 0xcd, 0xaa, 0xd8, 0x98, 0x85, 0x41, 0x4c, 0x44, 0x94, 0xc8, 0x5c, + 0x46, 0xc9, 0x20, 0xdf, 0x95, 0x5a, 0x74, 0xec, 0x9a, 0x1d, 0xf3, 0xf7, 0x4d, 0xd8, 0xb4, 0x49, + 0x1c, 0x7a, 0x13, 0x92, 0x26, 0x9a, 0xf3, 0x69, 0x15, 0x7e, 0x09, 0x2d, 0xcc, 0x98, 0x76, 0x93, + 0x07, 0x67, 0x56, 0x8c, 0x6d, 0xc1, 0x15, 0x7d, 0x00, 0x1b, 0xd8, 0x3f, 0xa6, 0x6e, 0x12, 0x26, + 0x71, 0x7a, 0x2c, 0xe9, 0x54, 0x5d, 0x7b, 0x76, 0xc3, 0x74, 0xe0, 0xea, 0x8c, 0x09, 0xb4, 0x39, + 0x8b, 0x0d, 0x4d, 0xa3, 0xd2, 0xd0, 0xd4, 0x0a, 0x69, 0x9e, 0x24, 0xe4, 0x1f, 0x0d, 0x58, 0xcf, + 0x43, 0x47, 0xb3, 0xbf, 0x0e, 0x5d, 0x5f, 0xc3, 0x62, 0xa3, 0x21, 0x0b, 0x56, 0x0e, 0x28, 0xf7, + 0x36, 0xcd, 0x6a, 0x6f, 0xb3, 0x09, 0x4b, 0xaa, 0xf5, 0xd4, 0x07, 0xd3, 0xab, 0x92, 0xca, 0xed, + 0x8a, 0xca, 0x5b, 0x00, 0x71, 0x96, 0xbf, 0x8c, 0x25, 0xb9, 0x5b, 0x80, 0x20, 0x13, 0x2e, 0xa8, + 0x4a, 0x68, 0x93, 0x38, 0xf1, 0xb8, 0xb1, 0x2c, 0x31, 0x4a, 0x30, 0x33, 0x84, 0xb5, 0x47, 0x54, + 0x9c, 0x61, 0x18, 0x9f, 0x8f, 0xb3, 0x7f, 0x0c, 0x6d, 0x21, 0x4c, 0x1c, 0xec, 0x38, 0xc2, 0x81, + 0x33, 0x22, 0xa9, 0xad, 0xb2, 0xb5, 0x08, 0x63, 0x8e, 0xdd, 0xd8, 0x68, 0x4a, 0xb8, 0xfc, 0x36, + 0xff, 0xda, 0x54, 0x9a, 0xee, 0x31, 0x16, 0x7f, 0xf3, 0xed, 0x6f, 0x7d, 0x41, 0x6e, 0xcd, 0x16, + 0xe4, 0x8a, 0xca, 0x5f, 0xa7, 0x20, 0x9f, 0x51, 0x99, 0x32, 0x13, 0x58, 0xde, 0x63, 0x4c, 0x28, + 0x82, 0x6e, 0x41, 0x1b, 0x33, 0xa6, 0x0c, 0x5e, 0xc9, 0xc8, 0x1a, 0x45, 0xfc, 0xd7, 0x2a, 0x49, + 0xd4, 0xde, 0x27, 0xd0, 0xcd, 0x40, 0xaf, 0x13, 0xdb, 0x2d, 0x8a, 0xdd, 0x06, 0x50, 0x1d, 0xe7, + 0x83, 0x60, 0x18, 0x8a, 0x2b, 0x15, 0xce, 0xae, 0x49, 0xe5, 0xb7, 0x79, 0x27, 0xc5, 0x90, 0xba, + 0x7d, 0x00, 0x8b, 0x94, 0x13, 0x3f, 0x55, 0x6e, 0xb3, 0xa8, 0x5c, 0xce, 0xc8, 0x56, 0x48, 0xe6, + 0x3f, 0x3b, 0x70, 0x4d, 0xdc, 0xd8, 0x53, 0x19, 0x26, 0x7b, 0x8c, 0x7d, 0x41, 0x38, 0xa6, 0x5e, + 0xfc, 0x93, 0x84, 0x44, 0xd3, 0xb7, 0xec, 0x18, 0x2e, 0x2c, 0xa9, 0x28, 0xd3, 0xf9, 0xee, 0xcc, + 0x87, 0x0f, 0xcd, 0x3e, 0x9f, 0x38, 0x5a, 0x6f, 0x67, 0xe2, 0xa8, 0x9b, 0x00, 0xda, 0xe7, 0x34, + 0x01, 0x9c, 0x3c, 0x04, 0x16, 0x46, 0xcb, 0xa5, 0xf2, 0x68, 0x59, 0xd3, 0x58, 0x2f, 0xbf, 0x69, + 0x63, 0xdd, 0xa9, 0x6d, 0xac, 0xfd, 0xda, 0x38, 0xee, 0x4a, 0x73, 0xff, 0xa8, 0xe8, 0x81, 0x27, + 0xfa, 0xda, 0x3c, 0x2d, 0x36, 0xbc, 0xd5, 0x16, 0xfb, 0xa7, 0xa5, 0x96, 0x59, 0x0d, 0xad, 0x1f, + 0xbd, 0xd9, 0x99, 0xbe, 0x4d, 0xcd, 0xf3, 0x1f, 0x64, 0xcf, 0xc4, 0xc2, 0xdc, 0x06, 0x59, 0x41, + 0x17, 0x75, 0x48, 0x94, 0x56, 0x9d, 0xb4, 0xc4, 0x37, 0xba, 0x09, 0x6d, 0x61, 0x64, 0xdd, 0xd4, + 0x5e, 0x2d, 0xda, 0x53, 0xdc, 0xc4, 0x1e, 0x63, 0x4f, 0x19, 0x71, 0x6c, 0x89, 0x84, 0xee, 0x40, + 0x37, 0x73, 0x7c, 0x1d, 0x59, 0xd7, 0x8b, 0x14, 0x59, 0x9c, 0xa4, 0x64, 0x39, 0xba, 0xa0, 0x1d, + 0xd0, 0x88, 0x38, 0xb2, 0xe5, 0x5b, 0x9c, 0xa5, 0xfd, 0x22, 0xdd, 0xcc, 0x68, 0x33, 0x74, 0x74, + 0x0b, 0x96, 0xd4, 0x94, 0x2f, 0x23, 0x68, 0x65, 0xf7, 0xda, 0x6c, 0x32, 0x4d, 0xa9, 0x34, 0xa2, + 0xf9, 0xf7, 0x06, 0xbc, 0x97, 0x3b, 0x44, 0x1a, 0x4d, 0x69, 0xd7, 0xfd, 0xcd, 0x57, 0xdc, 0x1b, + 0xb0, 0x2a, 0xdb, 0xfc, 0x7c, 0xd8, 0x57, 0xef, 0x4e, 0x15, 0xa8, 0xf9, 0xb7, 0x26, 0xac, 0x14, + 0x2e, 0xa2, 0xae, 0xf0, 0x88, 0xc6, 0x49, 0xde, 0xbf, 0x1c, 0x90, 0x64, 0x72, 0xed, 0xda, 0x05, + 0x08, 0x1a, 0x03, 0x30, 0x1c, 0x61, 0x9f, 0x70, 0x12, 0x89, 0x8c, 0x28, 0x22, 0xe7, 0xe1, 0xfc, + 0x51, 0x7a, 0x94, 0xf2, 0xb4, 0x0b, 0xec, 0x45, 0xe7, 0x27, 0x45, 0xc7, 0x3a, 0x0f, 0xea, 0x15, + 0xfa, 0x2d, 0xac, 0x0e, 0xa9, 0x47, 0x8e, 0x72, 0x45, 0x96, 0xa4, 0x22, 0x4f, 0xe6, 0x57, 0xe4, + 0x5e, 0x91, 0xaf, 0x5d, 0x11, 0x63, 0xbe, 0x0f, 0xeb, 0x55, 0xbf, 0x14, 0x4a, 0x52, 0x1f, 0xbb, + 0x99, 0xb5, 0xf4, 0xca, 0x44, 0xb0, 0x5e, 0xf5, 0x43, 0xf3, 0xbf, 0x4d, 0xb8, 0x92, 0xb1, 0xdb, + 0x0b, 0x82, 0x30, 0x09, 0x1c, 0xf9, 0x00, 0x55, 0x7b, 0x17, 0x97, 0x61, 0x91, 0x53, 0xee, 0x65, + 0x0d, 0x84, 0x5c, 0x88, 0x1a, 0xc0, 0xc3, 0xd0, 0xe3, 0x94, 0xe9, 0x7e, 0x38, 0x5d, 0x2a, 0x1f, + 0x79, 0x91, 0xd0, 0x88, 0x0c, 0x64, 0x44, 0x75, 0xec, 0x6c, 0x2d, 0xf6, 0x44, 0x77, 0x20, 0xdb, + 0x61, 0x65, 0xcc, 0x6c, 0x2d, 0xfd, 0x27, 0xf4, 0x3c, 0xe2, 0x08, 0x73, 0x14, 0x1a, 0xe6, 0x0a, + 0x54, 0x36, 0xe2, 0x3c, 0xa2, 0x81, 0xab, 0xdb, 0x65, 0xbd, 0x12, 0x7a, 0xe2, 0x28, 0xc2, 0x53, + 0xa3, 0x23, 0x0d, 0xa0, 0x16, 0xe8, 0x87, 0xd0, 0xf2, 0x31, 0xd3, 0x05, 0xe3, 0xfd, 0x52, 0x94, + 0xd5, 0x59, 0xc0, 0x3a, 0xc4, 0x4c, 0x65, 0x54, 0x41, 0xd6, 0xfb, 0x18, 0x3a, 0x29, 0xe0, 0x6b, + 0xb5, 0x56, 0x5f, 0xc1, 0xc5, 0x52, 0x10, 0xa3, 0x2f, 0x61, 0x33, 0xf7, 0xa8, 0xa2, 0x40, 0xdd, + 0x4c, 0xbd, 0xf7, 0x5a, 0xcd, 0xec, 0x13, 0x18, 0x98, 0x2f, 0x60, 0x43, 0xb8, 0xcc, 0xfe, 0x08, + 0x47, 0xfc, 0x9c, 0x46, 0x84, 0x4f, 0xa1, 0x9b, 0x89, 0xac, 0xf5, 0x99, 0x1e, 0x74, 0x26, 0xe9, + 0xc3, 0xa0, 0x9a, 0x11, 0xb2, 0xb5, 0xb9, 0x07, 0xa8, 0xa8, 0xaf, 0xce, 0xe4, 0x37, 0xcb, 0xcd, + 0xe5, 0x95, 0x6a, 0xda, 0x96, 0xe8, 0xba, 0xb7, 0xdc, 0xfd, 0xd3, 0x32, 0x6c, 0xe4, 0xa9, 0x50, + 0xfc, 0xa5, 0x0e, 0x41, 0x4f, 0x60, 0xfd, 0xbe, 0x7e, 0xaf, 0x4f, 0x27, 0x3f, 0x74, 0xda, 0x53, + 0x4a, 0xef, 0x7a, 0xfd, 0xa6, 0xd2, 0xc8, 0x5c, 0x40, 0x0e, 0x5c, 0xab, 0x32, 0xcc, 0x5f, 0x6d, + 0xbe, 0x7b, 0x0a, 0xe7, 0x0c, 0xeb, 0x75, 0x22, 0x76, 0x1a, 0xe8, 0x4b, 0x58, 0x2d, 0xbf, 0x2d, + 0xa0, 0x92, 0x2f, 0xd4, 0x3e, 0x77, 0xf4, 0xcc, 0xd3, 0x50, 0x32, 0xfd, 0x9f, 0x8b, 0x02, 0x5e, + 0x1a, 0xb4, 0x91, 0x59, 0x6e, 0x2f, 0xea, 0x1e, 0x22, 0x7a, 0xdf, 0x39, 0x15, 0x27, 0xe3, 0xfe, + 0x29, 0x74, 0xd2, 0xc1, 0xb4, 0x6c, 0xe6, 0xca, 0xb8, 0xda, 0x5b, 0x2f, 0xf3, 0x1b, 0xc6, 0xe6, + 0x02, 0xfa, 0x4c, 0x11, 0x8b, 0xc1, 0x65, 0x96, 0xb8, 0x30, 0x8e, 0xf5, 0x2e, 0xd5, 0x8c, 0x40, + 0xe6, 0x02, 0xfa, 0x31, 0xac, 0x88, 0xaf, 0x23, 0xfd, 0x52, 0xbe, 0x69, 0xa9, 0x1f, 0x66, 0xac, + 0xf4, 0x87, 0x19, 0xeb, 0xae, 0xcf, 0xf8, 0xb4, 0x57, 0x33, 0xa3, 0x68, 0x06, 0xcf, 0xe1, 0xe2, + 0x7d, 0xc2, 0xf3, 0x96, 0x02, 0x7d, 0xef, 0x8d, 0x1a, 0xaf, 0x9e, 0x59, 0x45, 0x9b, 0xed, 0x4a, + 0xcc, 0x05, 0xf4, 0xe7, 0x06, 0x5c, 0xba, 0x4f, 0x78, 0xb5, 0x48, 0xa3, 0x0f, 0xeb, 0x85, 0x9c, + 0x50, 0xcc, 0x7b, 0x8f, 0xe7, 0x8d, 0xdb, 0x32, 0x5b, 0x73, 0x01, 0x1d, 0xc9, 0x63, 0xe7, 0xf1, + 0x87, 0xde, 0xad, 0x0d, 0xb4, 0xcc, 0xfc, 0x5b, 0x27, 0x6d, 0xa7, 0x47, 0xfd, 0x7c, 0xef, 0x5f, + 0xaf, 0xb6, 0x1a, 0xff, 0x7e, 0xb5, 0xd5, 0xf8, 0xdf, 0xab, 0xad, 0xc6, 0x2f, 0x6e, 0xbf, 0xe6, + 0xe7, 0xb6, 0xc2, 0x2f, 0x78, 0x98, 0x51, 0xc7, 0xa3, 0x24, 0xe0, 0xc7, 0x4b, 0xf2, 0xd6, 0x6e, + 0xff, 0x3f, 0x00, 0x00, 0xff, 0xff, 0x46, 0x3e, 0x2d, 0xff, 0xe0, 0x1b, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -2433,6 +2463,46 @@ func (m *ManifestRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + if len(m.RefSources) > 0 { + for k := range m.RefSources { + v := m.RefSources[k] + baseI := i + if v != nil { + { + size, err := v.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintRepository(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + i -= len(k) + copy(dAtA[i:], k) + i = encodeVarintRepository(dAtA, i, uint64(len(k))) + i-- + dAtA[i] = 0xa + i = encodeVarintRepository(dAtA, i, uint64(baseI-i)) + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0xba + } + } + if m.HasMultipleSources { + i-- + if m.HasMultipleSources { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0xb0 + } if m.HelmOptions != nil { { size, err := m.HelmOptions.MarshalToSizedBuffer(dAtA[:i]) @@ -3356,6 +3426,32 @@ func (m *RepoServerAppDetailsQuery) MarshalToSizedBuffer(dAtA []byte) (int, erro i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + if len(m.RefSources) > 0 { + for k := range m.RefSources { + v := m.RefSources[k] + baseI := i + if v != nil { + { + size, err := v.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintRepository(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + i -= len(k) + copy(dAtA[i:], k) + i = encodeVarintRepository(dAtA, i, uint64(len(k))) + i-- + dAtA[i] = 0xa + i = encodeVarintRepository(dAtA, i, uint64(baseI-i)) + i-- + dAtA[i] = 0x5a + } + } if m.HelmOptions != nil { { size, err := m.HelmOptions.MarshalToSizedBuffer(dAtA[:i]) @@ -4125,6 +4221,22 @@ func (m *ManifestRequest) Size() (n int) { l = m.HelmOptions.Size() n += 2 + l + sovRepository(uint64(l)) } + if m.HasMultipleSources { + n += 3 + } + if len(m.RefSources) > 0 { + for k, v := range m.RefSources { + _ = k + _ = v + l = 0 + if v != nil { + l = v.Size() + l += 1 + sovRepository(uint64(l)) + } + mapEntrySize := 1 + len(k) + sovRepository(uint64(len(k))) + l + n += mapEntrySize + 2 + sovRepository(uint64(mapEntrySize)) + } + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -4502,6 +4614,19 @@ func (m *RepoServerAppDetailsQuery) Size() (n int) { l = m.HelmOptions.Size() n += 1 + l + sovRepository(uint64(l)) } + if len(m.RefSources) > 0 { + for k, v := range m.RefSources { + _ = k + _ = v + l = 0 + if v != nil { + l = v.Size() + l += 1 + sovRepository(uint64(l)) + } + mapEntrySize := 1 + len(k) + sovRepository(uint64(len(k))) + l + n += mapEntrySize + 1 + sovRepository(uint64(mapEntrySize)) + } + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -5438,6 +5563,155 @@ func (m *ManifestRequest) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 22: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field HasMultipleSources", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRepository + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.HasMultipleSources = bool(v != 0) + case 23: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field RefSources", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRepository + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthRepository + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthRepository + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.RefSources == nil { + m.RefSources = make(map[string]*v1alpha1.RefTarget) + } + var mapkey string + var mapvalue *v1alpha1.RefTarget + for iNdEx < postIndex { + entryPreIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRepository + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + if fieldNum == 1 { + var stringLenmapkey uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRepository + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLenmapkey |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLenmapkey := int(stringLenmapkey) + if intStringLenmapkey < 0 { + return ErrInvalidLengthRepository + } + postStringIndexmapkey := iNdEx + intStringLenmapkey + if postStringIndexmapkey < 0 { + return ErrInvalidLengthRepository + } + if postStringIndexmapkey > l { + return io.ErrUnexpectedEOF + } + mapkey = string(dAtA[iNdEx:postStringIndexmapkey]) + iNdEx = postStringIndexmapkey + } else if fieldNum == 2 { + var mapmsglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRepository + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + mapmsglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if mapmsglen < 0 { + return ErrInvalidLengthRepository + } + postmsgIndex := iNdEx + mapmsglen + if postmsgIndex < 0 { + return ErrInvalidLengthRepository + } + if postmsgIndex > l { + return io.ErrUnexpectedEOF + } + mapvalue = &v1alpha1.RefTarget{} + if err := mapvalue.Unmarshal(dAtA[iNdEx:postmsgIndex]); err != nil { + return err + } + iNdEx = postmsgIndex + } else { + iNdEx = entryPreIndex + skippy, err := skipRepository(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthRepository + } + if (iNdEx + skippy) > postIndex { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + m.RefSources[mapkey] = mapvalue + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipRepository(dAtA[iNdEx:]) @@ -7682,6 +7956,135 @@ func (m *RepoServerAppDetailsQuery) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 11: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field RefSources", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRepository + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthRepository + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthRepository + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.RefSources == nil { + m.RefSources = make(map[string]*v1alpha1.RefTarget) + } + var mapkey string + var mapvalue *v1alpha1.RefTarget + for iNdEx < postIndex { + entryPreIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRepository + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + if fieldNum == 1 { + var stringLenmapkey uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRepository + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLenmapkey |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLenmapkey := int(stringLenmapkey) + if intStringLenmapkey < 0 { + return ErrInvalidLengthRepository + } + postStringIndexmapkey := iNdEx + intStringLenmapkey + if postStringIndexmapkey < 0 { + return ErrInvalidLengthRepository + } + if postStringIndexmapkey > l { + return io.ErrUnexpectedEOF + } + mapkey = string(dAtA[iNdEx:postStringIndexmapkey]) + iNdEx = postStringIndexmapkey + } else if fieldNum == 2 { + var mapmsglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRepository + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + mapmsglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if mapmsglen < 0 { + return ErrInvalidLengthRepository + } + postmsgIndex := iNdEx + mapmsglen + if postmsgIndex < 0 { + return ErrInvalidLengthRepository + } + if postmsgIndex > l { + return io.ErrUnexpectedEOF + } + mapvalue = &v1alpha1.RefTarget{} + if err := mapvalue.Unmarshal(dAtA[iNdEx:postmsgIndex]); err != nil { + return err + } + iNdEx = postmsgIndex + } else { + iNdEx = entryPreIndex + skippy, err := skipRepository(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthRepository + } + if (iNdEx + skippy) > postIndex { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + m.RefSources[mapkey] = mapvalue + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipRepository(dAtA[iNdEx:]) diff --git a/reposerver/cache/cache.go b/reposerver/cache/cache.go index 417df72280284..61b4ff6abd85b 100644 --- a/reposerver/cache/cache.go +++ b/reposerver/cache/cache.go @@ -62,17 +62,51 @@ func AddCacheFlagsToCmd(cmd *cobra.Command, opts ...func(client *redis.Client)) } } -func appSourceKey(appSrc *appv1.ApplicationSource) uint32 { - return hash.FNVa(appSourceKeyJSON(appSrc)) +type refTargetForCacheKey struct { + RepoURL string `json:"repoURL"` + Project string `json:"project"` + TargetRevision string `json:"targetRevision"` + Chart string `json:"chart"` +} + +func refTargetForCacheKeyFromRefTarget(refTarget *appv1.RefTarget) refTargetForCacheKey { + return refTargetForCacheKey{ + RepoURL: refTarget.Repo.Repo, + Project: refTarget.Repo.Project, + TargetRevision: refTarget.TargetRevision, + Chart: refTarget.Chart, + } +} + +type refTargetRevisionMappingForCacheKey map[string]refTargetForCacheKey + +func getRefTargetRevisionMappingForCacheKey(refTargetRevisionMapping appv1.RefTargetRevisionMapping) refTargetRevisionMappingForCacheKey { + res := make(refTargetRevisionMappingForCacheKey) + for k, v := range refTargetRevisionMapping { + res[k] = refTargetForCacheKeyFromRefTarget(v) + } + return res } -func appSourceKeyJSON(appSrc *appv1.ApplicationSource) string { +func appSourceKey(appSrc *appv1.ApplicationSource, srcRefs appv1.RefTargetRevisionMapping) uint32 { + return hash.FNVa(appSourceKeyJSON(appSrc, srcRefs)) +} + +type appSourceKeyStruct struct { + AppSrc *appv1.ApplicationSource `json:"appSrc"` + SrcRefs refTargetRevisionMappingForCacheKey `json:"srcRefs"` +} + +func appSourceKeyJSON(appSrc *appv1.ApplicationSource, srcRefs appv1.RefTargetRevisionMapping) string { appSrc = appSrc.DeepCopy() if !appSrc.IsHelm() { appSrc.RepoURL = "" // superseded by commitSHA appSrc.TargetRevision = "" // superseded by commitSHA } - appSrcStr, _ := json.Marshal(appSrc) + appSrcStr, _ := json.Marshal(appSourceKeyStruct{ + AppSrc: appSrc, + SrcRefs: getRefTargetRevisionMappingForCacheKey(srcRefs), + }) return string(appSrcStr) } @@ -149,9 +183,9 @@ func (c *Cache) GetGitReferences(repo string, references *[]*plumbing.Reference) return nil } -func manifestCacheKey(revision string, appSrc *appv1.ApplicationSource, namespace string, trackingMethod string, appLabelKey string, appName string, info ClusterRuntimeInfo) string { +func manifestCacheKey(revision string, appSrc *appv1.ApplicationSource, srcRefs appv1.RefTargetRevisionMapping, namespace string, trackingMethod string, appLabelKey string, appName string, info ClusterRuntimeInfo) string { trackingKey := trackingKey(appLabelKey, trackingMethod) - return fmt.Sprintf("mfst|%s|%s|%s|%s|%d", trackingKey, appName, revision, namespace, appSourceKey(appSrc)+clusterRuntimeInfoKey(info)) + return fmt.Sprintf("mfst|%s|%s|%s|%s|%d", trackingKey, appName, revision, namespace, appSourceKey(appSrc, srcRefs)+clusterRuntimeInfoKey(info)) } func trackingKey(appLabelKey string, trackingMethod string) string { @@ -164,11 +198,11 @@ func trackingKey(appLabelKey string, trackingMethod string) string { // LogDebugManifestCacheKeyFields logs all the information included in a manifest cache key. It's intended to be run // before every manifest cache operation to help debug cache misses. -func LogDebugManifestCacheKeyFields(message string, reason string, revision string, appSrc *appv1.ApplicationSource, clusterInfo ClusterRuntimeInfo, namespace string, trackingMethod string, appLabelKey string, appName string) { +func LogDebugManifestCacheKeyFields(message string, reason string, revision string, appSrc *appv1.ApplicationSource, srcRefs appv1.RefTargetRevisionMapping, clusterInfo ClusterRuntimeInfo, namespace string, trackingMethod string, appLabelKey string, appName string) { if log.IsLevelEnabled(log.DebugLevel) { log.WithFields(log.Fields{ "revision": revision, - "appSrc": appSourceKeyJSON(appSrc), + "appSrc": appSourceKeyJSON(appSrc, srcRefs), "namespace": namespace, "trackingKey": trackingKey(appLabelKey, trackingMethod), "appName": appName, @@ -178,8 +212,8 @@ func LogDebugManifestCacheKeyFields(message string, reason string, revision stri } } -func (c *Cache) GetManifests(revision string, appSrc *appv1.ApplicationSource, clusterInfo ClusterRuntimeInfo, namespace string, trackingMethod string, appLabelKey string, appName string, res *CachedManifestResponse) error { - err := c.cache.GetItem(manifestCacheKey(revision, appSrc, namespace, trackingMethod, appLabelKey, appName, clusterInfo), res) +func (c *Cache) GetManifests(revision string, appSrc *appv1.ApplicationSource, srcRefs appv1.RefTargetRevisionMapping, clusterInfo ClusterRuntimeInfo, namespace string, trackingMethod string, appLabelKey string, appName string, res *CachedManifestResponse) error { + err := c.cache.GetItem(manifestCacheKey(revision, appSrc, srcRefs, namespace, trackingMethod, appLabelKey, appName, clusterInfo), res) if err != nil { return err @@ -194,9 +228,9 @@ func (c *Cache) GetManifests(revision string, appSrc *appv1.ApplicationSource, c if hash != res.CacheEntryHash || res.ManifestResponse == nil && res.MostRecentError == "" { log.Warnf("Manifest hash did not match expected value or cached manifests response is empty, treating as a cache miss: %s", appName) - LogDebugManifestCacheKeyFields("deleting manifests cache", "manifest hash did not match or cached response is empty", revision, appSrc, clusterInfo, namespace, trackingMethod, appLabelKey, appName) + LogDebugManifestCacheKeyFields("deleting manifests cache", "manifest hash did not match or cached response is empty", revision, appSrc, srcRefs, clusterInfo, namespace, trackingMethod, appLabelKey, appName) - err = c.DeleteManifests(revision, appSrc, clusterInfo, namespace, trackingMethod, appLabelKey, appName) + err = c.DeleteManifests(revision, appSrc, srcRefs, clusterInfo, namespace, trackingMethod, appLabelKey, appName) if err != nil { return fmt.Errorf("Unable to delete manifest after hash mismatch, %v", err) } @@ -211,7 +245,7 @@ func (c *Cache) GetManifests(revision string, appSrc *appv1.ApplicationSource, c return nil } -func (c *Cache) SetManifests(revision string, appSrc *appv1.ApplicationSource, clusterInfo ClusterRuntimeInfo, namespace string, trackingMethod string, appLabelKey string, appName string, res *CachedManifestResponse) error { +func (c *Cache) SetManifests(revision string, appSrc *appv1.ApplicationSource, srcRefs appv1.RefTargetRevisionMapping, clusterInfo ClusterRuntimeInfo, namespace string, trackingMethod string, appLabelKey string, appName string, res *CachedManifestResponse) error { // Generate and apply the cache entry hash, before writing if res != nil { res = res.shallowCopy() @@ -222,26 +256,26 @@ func (c *Cache) SetManifests(revision string, appSrc *appv1.ApplicationSource, c res.CacheEntryHash = hash } - return c.cache.SetItem(manifestCacheKey(revision, appSrc, namespace, trackingMethod, appLabelKey, appName, clusterInfo), res, c.repoCacheExpiration, res == nil) + return c.cache.SetItem(manifestCacheKey(revision, appSrc, srcRefs, namespace, trackingMethod, appLabelKey, appName, clusterInfo), res, c.repoCacheExpiration, res == nil) } -func (c *Cache) DeleteManifests(revision string, appSrc *appv1.ApplicationSource, clusterInfo ClusterRuntimeInfo, namespace, trackingMethod, appLabelKey, appName string) error { - return c.cache.SetItem(manifestCacheKey(revision, appSrc, namespace, trackingMethod, appLabelKey, appName, clusterInfo), "", c.repoCacheExpiration, true) +func (c *Cache) DeleteManifests(revision string, appSrc *appv1.ApplicationSource, srcRefs appv1.RefTargetRevisionMapping, clusterInfo ClusterRuntimeInfo, namespace, trackingMethod, appLabelKey, appName string) error { + return c.cache.SetItem(manifestCacheKey(revision, appSrc, srcRefs, namespace, trackingMethod, appLabelKey, appName, clusterInfo), "", c.repoCacheExpiration, true) } -func appDetailsCacheKey(revision string, appSrc *appv1.ApplicationSource, trackingMethod appv1.TrackingMethod) string { +func appDetailsCacheKey(revision string, appSrc *appv1.ApplicationSource, srcRefs appv1.RefTargetRevisionMapping, trackingMethod appv1.TrackingMethod) string { if trackingMethod == "" { trackingMethod = argo.TrackingMethodLabel } - return fmt.Sprintf("appdetails|%s|%d|%s", revision, appSourceKey(appSrc), trackingMethod) + return fmt.Sprintf("appdetails|%s|%d|%s", revision, appSourceKey(appSrc, srcRefs), trackingMethod) } -func (c *Cache) GetAppDetails(revision string, appSrc *appv1.ApplicationSource, res *apiclient.RepoAppDetailsResponse, trackingMethod appv1.TrackingMethod) error { - return c.cache.GetItem(appDetailsCacheKey(revision, appSrc, trackingMethod), res) +func (c *Cache) GetAppDetails(revision string, appSrc *appv1.ApplicationSource, srcRefs appv1.RefTargetRevisionMapping, res *apiclient.RepoAppDetailsResponse, trackingMethod appv1.TrackingMethod) error { + return c.cache.GetItem(appDetailsCacheKey(revision, appSrc, srcRefs, trackingMethod), res) } -func (c *Cache) SetAppDetails(revision string, appSrc *appv1.ApplicationSource, res *apiclient.RepoAppDetailsResponse, trackingMethod appv1.TrackingMethod) error { - return c.cache.SetItem(appDetailsCacheKey(revision, appSrc, trackingMethod), res, c.repoCacheExpiration, res == nil) +func (c *Cache) SetAppDetails(revision string, appSrc *appv1.ApplicationSource, srcRefs appv1.RefTargetRevisionMapping, res *apiclient.RepoAppDetailsResponse, trackingMethod appv1.TrackingMethod) error { + return c.cache.SetItem(appDetailsCacheKey(revision, appSrc, srcRefs, trackingMethod), res, c.repoCacheExpiration, res == nil) } func revisionMetadataKey(repoURL, revision string) string { diff --git a/reposerver/cache/cache_test.go b/reposerver/cache/cache_test.go index 805fad88a44da..747962c5ccaf3 100644 --- a/reposerver/cache/cache_test.go +++ b/reposerver/cache/cache_test.go @@ -73,50 +73,57 @@ func TestCache_GetManifests(t *testing.T) { // cache miss q := &apiclient.ManifestRequest{} value := &CachedManifestResponse{} - err := cache.GetManifests("my-revision", &ApplicationSource{}, q, "my-namespace", "", "my-app-label-key", "my-app-label-value", value) + err := cache.GetManifests("my-revision", &ApplicationSource{}, q.RefSources, q, "my-namespace", "", "my-app-label-key", "my-app-label-value", value) assert.Equal(t, ErrCacheMiss, err) // populate cache res := &CachedManifestResponse{ManifestResponse: &apiclient.ManifestResponse{SourceType: "my-source-type"}} - err = cache.SetManifests("my-revision", &ApplicationSource{}, q, "my-namespace", "", "my-app-label-key", "my-app-label-value", res) + err = cache.SetManifests("my-revision", &ApplicationSource{}, q.RefSources, q, "my-namespace", "", "my-app-label-key", "my-app-label-value", res) assert.NoError(t, err) - // cache miss - err = cache.GetManifests("other-revision", &ApplicationSource{}, q, "my-namespace", "", "my-app-label-key", "my-app-label-value", value) - assert.Equal(t, ErrCacheMiss, err) - // cache miss - err = cache.GetManifests("my-revision", &ApplicationSource{Path: "other-path"}, q, "my-namespace", "", "my-app-label-key", "my-app-label-value", value) - assert.Equal(t, ErrCacheMiss, err) - // cache miss - err = cache.GetManifests("my-revision", &ApplicationSource{}, q, "other-namespace", "", "my-app-label-key", "my-app-label-value", value) - assert.Equal(t, ErrCacheMiss, err) - // cache miss - err = cache.GetManifests("my-revision", &ApplicationSource{}, q, "my-namespace", "", "other-app-label-key", "my-app-label-value", value) - assert.Equal(t, ErrCacheMiss, err) - // cache miss - err = cache.GetManifests("my-revision", &ApplicationSource{}, q, "my-namespace", "", "my-app-label-key", "other-app-label-value", value) - assert.Equal(t, ErrCacheMiss, err) - // cache hit - err = cache.GetManifests("my-revision", &ApplicationSource{}, q, "my-namespace", "", "my-app-label-key", "my-app-label-value", value) - assert.NoError(t, err) - assert.Equal(t, &CachedManifestResponse{ManifestResponse: &apiclient.ManifestResponse{SourceType: "my-source-type"}}, value) + t.Run("expect cache miss because of changed revision", func(t *testing.T) { + err = cache.GetManifests("other-revision", &ApplicationSource{}, q.RefSources, q, "my-namespace", "", "my-app-label-key", "my-app-label-value", value) + assert.Equal(t, ErrCacheMiss, err) + }) + t.Run("expect cache miss because of changed path", func(t *testing.T) { + err = cache.GetManifests("my-revision", &ApplicationSource{Path: "other-path"}, q.RefSources, q, "my-namespace", "", "my-app-label-key", "my-app-label-value", value) + assert.Equal(t, ErrCacheMiss, err) + }) + t.Run("expect cache miss because of changed namespace", func(t *testing.T) { + err = cache.GetManifests("my-revision", &ApplicationSource{}, q.RefSources, q, "other-namespace", "", "my-app-label-key", "my-app-label-value", value) + assert.Equal(t, ErrCacheMiss, err) + }) + t.Run("expect cache miss because of changed app label key", func(t *testing.T) { + err = cache.GetManifests("my-revision", &ApplicationSource{}, q.RefSources, q, "my-namespace", "", "other-app-label-key", "my-app-label-value", value) + assert.Equal(t, ErrCacheMiss, err) + }) + t.Run("expect cache miss because of changed app label value", func(t *testing.T) { + err = cache.GetManifests("my-revision", &ApplicationSource{}, q.RefSources, q, "my-namespace", "", "my-app-label-key", "other-app-label-value", value) + 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) + assert.NoError(t, err) + assert.Equal(t, &CachedManifestResponse{ManifestResponse: &apiclient.ManifestResponse{SourceType: "my-source-type"}}, value) + }) } func TestCache_GetAppDetails(t *testing.T) { cache := newFixtures().Cache // cache miss value := &apiclient.RepoAppDetailsResponse{} - err := cache.GetAppDetails("my-revision", &ApplicationSource{}, value, "") + emptyRefSources := map[string]*appv1.RefTarget{} + err := cache.GetAppDetails("my-revision", &ApplicationSource{}, emptyRefSources, value, "") assert.Equal(t, ErrCacheMiss, err) res := &apiclient.RepoAppDetailsResponse{Type: "my-type"} - err = cache.SetAppDetails("my-revision", &ApplicationSource{}, res, "") + err = cache.SetAppDetails("my-revision", &ApplicationSource{}, emptyRefSources, res, "") assert.NoError(t, err) //cache miss - err = cache.GetAppDetails("other-revision", &ApplicationSource{}, value, "") + err = cache.GetAppDetails("other-revision", &ApplicationSource{}, emptyRefSources, value, "") assert.Equal(t, ErrCacheMiss, err) //cache miss - err = cache.GetAppDetails("my-revision", &ApplicationSource{Path: "other-path"}, value, "") + err = cache.GetAppDetails("my-revision", &ApplicationSource{Path: "other-path"}, emptyRefSources, value, "") assert.Equal(t, ErrCacheMiss, err) // cache hit - err = cache.GetAppDetails("my-revision", &ApplicationSource{}, value, "") + err = cache.GetAppDetails("my-revision", &ApplicationSource{}, emptyRefSources, value, "") assert.NoError(t, err) assert.Equal(t, &apiclient.RepoAppDetailsResponse{Type: "my-type"}, value) } @@ -154,7 +161,8 @@ func TestCachedManifestResponse_HashBehavior(t *testing.T) { NumberOfCachedResponsesReturned: 0, NumberOfConsecutiveFailures: 0, } - err := repoCache.SetManifests(response.Revision, appSrc, &apiclient.ManifestRequest{}, response.Namespace, "", appKey, appValue, store) + q := &apiclient.ManifestRequest{} + err := repoCache.SetManifests(response.Revision, appSrc, q.RefSources, q, response.Namespace, "", appKey, appValue, store) if err != nil { t.Fatal(err) } @@ -185,7 +193,7 @@ func TestCachedManifestResponse_HashBehavior(t *testing.T) { // Retrieve the value using 'GetManifests' and confirm it works retrievedVal := &CachedManifestResponse{} - err = repoCache.GetManifests(response.Revision, appSrc, &apiclient.ManifestRequest{}, response.Namespace, "", appKey, appValue, retrievedVal) + err = repoCache.GetManifests(response.Revision, appSrc, q.RefSources, q, response.Namespace, "", appKey, appValue, retrievedVal) if err != nil { t.Fatal(err) } @@ -208,7 +216,7 @@ func TestCachedManifestResponse_HashBehavior(t *testing.T) { // Retrieve the value using GetManifests and confirm it returns a cache miss retrievedVal = &CachedManifestResponse{} - err = repoCache.GetManifests(response.Revision, appSrc, &apiclient.ManifestRequest{}, response.Namespace, "", appKey, appValue, retrievedVal) + err = repoCache.GetManifests(response.Revision, appSrc, q.RefSources, q, response.Namespace, "", appKey, appValue, retrievedVal) assert.True(t, err == cacheutil.ErrCacheMiss) diff --git a/reposerver/repository/repository.go b/reposerver/repository/repository.go index 98f2a4da2ecf6..d420a7bd915c9 100644 --- a/reposerver/repository/repository.go +++ b/reposerver/repository/repository.go @@ -83,8 +83,8 @@ var ErrExceededMaxCombinedManifestFileSize = errors.New("exceeded max combined m type Service struct { gitCredsStore git.CredsStore rootDir string - gitRepoPaths *io.TempPaths - chartPaths *io.TempPaths + gitRepoPaths io.TempPaths + chartPaths io.TempPaths gitRepoInitializer func(rootPath string) goio.Closer repoLock *repositoryLock cache *reposervercache.Cache @@ -118,6 +118,8 @@ func NewService(metricsServer *metrics.MetricsServer, cache *reposervercache.Cac parallelismLimitSemaphore = semaphore.NewWeighted(initConstants.ParallelismLimit) } repoLock := NewRepositoryLock() + gitRandomizedPaths := io.NewRandomizedTempPaths(rootDir) + helmRandomizedPaths := io.NewRandomizedTempPaths(rootDir) return &Service{ parallelismLimitSemaphore: parallelismLimitSemaphore, repoLock: repoLock, @@ -131,8 +133,8 @@ func NewService(metricsServer *metrics.MetricsServer, cache *reposervercache.Cac initConstants: initConstants, now: time.Now, gitCredsStore: gitCredsStore, - gitRepoPaths: io.NewTempPaths(rootDir), - chartPaths: io.NewTempPaths(rootDir), + gitRepoPaths: gitRandomizedPaths, + chartPaths: helmRandomizedPaths, gitRepoInitializer: directoryPermissionInitializer, rootDir: rootDir, } @@ -287,7 +289,8 @@ func (s *Service) runRepoOperation( verifyCommit bool, cacheFn func(cacheKey string, firstInvocation bool) (bool, error), operation func(repoRoot, commitSHA, cacheKey string, ctxSrc operationContextSrc) error, - settings operationSettings) error { + settings operationSettings, + hasMultipleSources bool) error { if sanitizer, ok := grpc.SanitizerFromContext(ctx); ok { // make sure randomized path replaced with '.' in the error message @@ -327,6 +330,14 @@ func (s *Service) runRepoOperation( defer settings.sem.Release(1) } + // do not generate manifests if Path and Chart fields are not set for a source in Multiple Sources + if hasMultipleSources && source.Path == "" && source.Chart == "" { + log.WithFields(map[string]interface{}{ + "source": source, + }).Warnf("not generating manifests as path and chart fields are empty") + return nil + } + if source.IsHelm() { if settings.noCache { err = helmClient.CleanChartCache(source.Chart, revision) @@ -426,7 +437,6 @@ func (s *Service) runRepoOperation( func (s *Service) GenerateManifest(ctx context.Context, q *apiclient.ManifestRequest) (*apiclient.ManifestResponse, error) { var res *apiclient.ManifestResponse var err error - cacheFn := func(cacheKey string, firstInvocation bool) (bool, error) { ok, resp, err := s.getManifestCacheEntry(cacheKey, q, firstInvocation) res = resp @@ -455,7 +465,7 @@ func (s *Service) GenerateManifest(ctx context.Context, q *apiclient.ManifestReq } settings := operationSettings{sem: s.parallelismLimitSemaphore, noCache: q.NoCache, noRevisionCache: q.NoRevisionCache, allowConcurrent: q.ApplicationSource.AllowsConcurrentProcessing()} - err = s.runRepoOperation(ctx, q.Revision, q.Repo, q.ApplicationSource, q.VerifySignature, cacheFn, operation, settings) + err = s.runRepoOperation(ctx, q.Revision, q.Repo, q.ApplicationSource, q.VerifySignature, cacheFn, operation, settings, q.HasMultipleSources) // if the tarDoneCh message is sent it means that the manifest // generation is being managed by the cmp-server. In this case @@ -470,6 +480,9 @@ func (s *Service) GenerateManifest(ctx context.Context, q *apiclient.ManifestReq } } + if q.HasMultipleSources && err == nil && res == nil { + res = &apiclient.ManifestResponse{} + } return res, err } @@ -582,6 +595,12 @@ func (s *Service) runManifestGen(ctx context.Context, repoRoot, commitSHA, cache return responsePromise } +type repoRef struct { + revision string + commitSHA string + key string +} + func (s *Service) runManifestGenAsync(ctx context.Context, repoRoot, commitSHA, cacheKey string, opContextSrc operationContextSrc, q *apiclient.ManifestRequest, ch *generateManifestCh) { defer func() { close(ch.errCh) @@ -595,17 +614,103 @@ func (s *Service) runManifestGenAsync(ctx context.Context, repoRoot, commitSHA, var manifestGenResult *apiclient.ManifestResponse opContext, err := opContextSrc() if err == nil { - manifestGenResult, err = GenerateManifests(ctx, opContext.appPath, repoRoot, commitSHA, q, false, s.gitCredsStore, s.initConstants.MaxCombinedDirectoryManifestsSize, WithCMPTarDoneChannel(ch.tarDoneCh), WithCMPTarExcludedGlobs(s.initConstants.CMPTarExcludedGlobs)) + if q.HasMultipleSources { + if q.ApplicationSource.Helm != nil { + repoRefs := make(map[string]repoRef) + + // Checkout every one of the referenced sources to the target revision before generating Manifests + for _, valueFile := range q.ApplicationSource.Helm.ValueFiles { + if strings.HasPrefix(valueFile, "$") { + refVar := strings.Split(valueFile, "/")[0] + + refSourceMapping, ok := q.RefSources[refVar] + if !ok { + if len(q.RefSources) == 0 { + ch.errCh <- fmt.Errorf("source referenced %q, but no source has a 'ref' field defined", refVar) + } + refKeys := make([]string, 0) + for refKey := range q.RefSources { + refKeys = append(refKeys, refKey) + } + ch.errCh <- fmt.Errorf("source referenced %q, which is not one of the available sources (%s)", refVar, strings.Join(refKeys, ", ")) + return + } + if refSourceMapping.Chart != "" { + ch.errCh <- fmt.Errorf("source has a 'chart' field defined, but Helm charts are not yet not supported for 'ref' sources") + return + } + normalizedRepoURL := git.NormalizeGitURL(refSourceMapping.Repo.Repo) + closer, ok := repoRefs[normalizedRepoURL] + if ok { + if closer.revision != refSourceMapping.TargetRevision { + ch.errCh <- fmt.Errorf("cannot reference multiple revisions for the same repository (%s references %q while %s references %q)", refVar, refSourceMapping.TargetRevision, closer.key, closer.revision) + return + } + } else { + gitClient, referencedCommitSHA, err := s.newClientResolveRevision(&refSourceMapping.Repo, refSourceMapping.TargetRevision) + if err != nil { + ch.errCh <- fmt.Errorf("failed to get git client for repo %s", q.Repo.Repo) + return + } + + if git.NormalizeGitURL(q.ApplicationSource.RepoURL) == normalizedRepoURL && commitSHA != referencedCommitSHA { + ch.errCh <- fmt.Errorf("cannot reference a different revision of the same repository (%s references %q which resolves to %q while the application references %q which resolves to %q)", refVar, refSourceMapping.TargetRevision, referencedCommitSHA, q.Revision, commitSHA) + return + } + closer, err := s.repoLock.Lock(gitClient.Root(), referencedCommitSHA, true, func() (goio.Closer, error) { + return s.checkoutRevision(gitClient, referencedCommitSHA, s.initConstants.SubmoduleEnabled) + }) + if err != nil { + log.Errorf("failed to acquire lock for referenced source %s", normalizedRepoURL) + ch.errCh <- err + return + } + defer func(closer goio.Closer) { + err := closer.Close() + if err != nil { + log.Errorf("Failed to release repo lock: %v", err) + } + }(closer) + + // Symlink check must happen after acquiring lock. + if !s.initConstants.AllowOutOfBoundsSymlinks { + err := argopath.CheckOutOfBoundsSymlinks(gitClient.Root()) + if err != nil { + oobError := &argopath.OutOfBoundsSymlinkError{} + if errors.As(err, &oobError) { + log.WithFields(log.Fields{ + common.SecurityField: common.SecurityHigh, + "repo": refSourceMapping.Repo, + "revision": refSourceMapping.TargetRevision, + "file": oobError.File, + }).Warn("repository contains out-of-bounds symlink") + ch.errCh <- fmt.Errorf("repository contains out-of-bounds symlinks. file: %s", oobError.File) + return + } else { + ch.errCh <- err + return + } + } + } + + repoRefs[normalizedRepoURL] = repoRef{revision: refSourceMapping.TargetRevision, commitSHA: referencedCommitSHA, key: refVar} + } + } + } + } + } + + manifestGenResult, err = GenerateManifests(ctx, opContext.appPath, repoRoot, commitSHA, q, false, s.gitCredsStore, s.initConstants.MaxCombinedDirectoryManifestsSize, s.gitRepoPaths, WithCMPTarDoneChannel(ch.tarDoneCh), WithCMPTarExcludedGlobs(s.initConstants.CMPTarExcludedGlobs)) } if err != nil { // If manifest generation error caching is enabled if s.initConstants.PauseGenerationAfterFailedGenerationAttempts > 0 { - cache.LogDebugManifestCacheKeyFields("getting manifests cache", "GenerateManifests error", cacheKey, q.ApplicationSource, q, q.Namespace, q.TrackingMethod, q.AppLabelKey, q.AppName) + cache.LogDebugManifestCacheKeyFields("getting manifests cache", "GenerateManifests error", cacheKey, q.ApplicationSource, q.RefSources, q, q.Namespace, q.TrackingMethod, q.AppLabelKey, q.AppName) // Retrieve a new copy (if available) of the cached response: this ensures we are updating the latest copy of the cache, // rather than a copy of the cache that occurred before (a potentially lengthy) manifest generation. innerRes := &cache.CachedManifestResponse{} - cacheErr := s.cache.GetManifests(cacheKey, appSourceCopy, q, q.Namespace, q.TrackingMethod, q.AppLabelKey, q.AppName, innerRes) + cacheErr := s.cache.GetManifests(cacheKey, appSourceCopy, q.RefSources, q, q.Namespace, q.TrackingMethod, q.AppLabelKey, q.AppName, innerRes) if cacheErr != nil && cacheErr != reposervercache.ErrCacheMiss { log.Warnf("manifest cache set error %s: %v", appSourceCopy.String(), cacheErr) ch.errCh <- cacheErr @@ -618,12 +723,12 @@ func (s *Service) runManifestGenAsync(ctx context.Context, repoRoot, commitSHA, innerRes.FirstFailureTimestamp = s.now().Unix() } - cache.LogDebugManifestCacheKeyFields("setting manifests cache", "GenerateManifests error", cacheKey, q.ApplicationSource, q, q.Namespace, q.TrackingMethod, q.AppLabelKey, q.AppName) + cache.LogDebugManifestCacheKeyFields("setting manifests cache", "GenerateManifests error", cacheKey, q.ApplicationSource, q.RefSources, q, q.Namespace, q.TrackingMethod, q.AppLabelKey, q.AppName) // Update the cache to include failure information innerRes.NumberOfConsecutiveFailures++ innerRes.MostRecentError = err.Error() - cacheErr = s.cache.SetManifests(cacheKey, appSourceCopy, q, q.Namespace, q.TrackingMethod, q.AppLabelKey, q.AppName, innerRes) + cacheErr = s.cache.SetManifests(cacheKey, appSourceCopy, q.RefSources, q, q.Namespace, q.TrackingMethod, q.AppLabelKey, q.AppName, innerRes) if cacheErr != nil { log.Warnf("manifest cache set error %s: %v", appSourceCopy.String(), cacheErr) ch.errCh <- cacheErr @@ -635,7 +740,7 @@ func (s *Service) runManifestGenAsync(ctx context.Context, repoRoot, commitSHA, return } - cache.LogDebugManifestCacheKeyFields("setting manifests cache", "fresh GenerateManifests response", cacheKey, q.ApplicationSource, q, q.Namespace, q.TrackingMethod, q.AppLabelKey, q.AppName) + cache.LogDebugManifestCacheKeyFields("setting manifests cache", "fresh GenerateManifests response", cacheKey, q.ApplicationSource, q.RefSources, q, q.Namespace, q.TrackingMethod, q.AppLabelKey, q.AppName) // Otherwise, no error occurred, so ensure the manifest generation error data in the cache entry is reset before we cache the value manifestGenCacheEntry := cache.CachedManifestResponse{ @@ -647,7 +752,7 @@ func (s *Service) runManifestGenAsync(ctx context.Context, repoRoot, commitSHA, } manifestGenResult.Revision = commitSHA manifestGenResult.VerifyResult = opContext.verificationResult - err = s.cache.SetManifests(cacheKey, appSourceCopy, q, q.Namespace, q.TrackingMethod, q.AppLabelKey, q.AppName, &manifestGenCacheEntry) + err = s.cache.SetManifests(cacheKey, appSourceCopy, q.RefSources, q, q.Namespace, q.TrackingMethod, q.AppLabelKey, q.AppName, &manifestGenCacheEntry) if err != nil { log.Warnf("manifest cache set error %s/%s: %v", appSourceCopy.String(), cacheKey, err) } @@ -661,10 +766,10 @@ func (s *Service) runManifestGenAsync(ctx context.Context, repoRoot, commitSHA, // and returns true otherwise. // If true is returned, either the second or third parameter (but not both) will contain a value from the cache (a ManifestResponse, or error, respectively) func (s *Service) getManifestCacheEntry(cacheKey string, q *apiclient.ManifestRequest, firstInvocation bool) (bool, *apiclient.ManifestResponse, error) { - cache.LogDebugManifestCacheKeyFields("getting manifests cache", "GenerateManifest API call", cacheKey, q.ApplicationSource, q, q.Namespace, q.TrackingMethod, q.AppLabelKey, q.AppName) + cache.LogDebugManifestCacheKeyFields("getting manifests cache", "GenerateManifest API call", cacheKey, q.ApplicationSource, q.RefSources, q, q.Namespace, q.TrackingMethod, q.AppLabelKey, q.AppName) res := cache.CachedManifestResponse{} - err := s.cache.GetManifests(cacheKey, q.ApplicationSource, q, q.Namespace, q.TrackingMethod, q.AppLabelKey, q.AppName, &res) + err := s.cache.GetManifests(cacheKey, q.ApplicationSource, q.RefSources, q, q.Namespace, q.TrackingMethod, q.AppLabelKey, q.AppName, &res) if err == nil { // The cache contains an existing value @@ -682,10 +787,10 @@ func (s *Service) getManifestCacheEntry(cacheKey string, q *apiclient.ManifestRe // After X minutes, reset the cache and retry the operation (e.g. perhaps the error is ephemeral and has passed) if elapsedTimeInMinutes >= s.initConstants.PauseGenerationOnFailureForMinutes { - cache.LogDebugManifestCacheKeyFields("deleting manifests cache", "manifest hash did not match or cached response is empty", cacheKey, q.ApplicationSource, q, q.Namespace, q.TrackingMethod, q.AppLabelKey, q.AppName) + cache.LogDebugManifestCacheKeyFields("deleting manifests cache", "manifest hash did not match or cached response is empty", cacheKey, q.ApplicationSource, q.RefSources, q, q.Namespace, q.TrackingMethod, q.AppLabelKey, q.AppName) // We can now try again, so reset the cache state and run the operation below - err = s.cache.DeleteManifests(cacheKey, q.ApplicationSource, q, q.Namespace, q.TrackingMethod, q.AppLabelKey, q.AppName) + err = s.cache.DeleteManifests(cacheKey, q.ApplicationSource, q.RefSources, q, q.Namespace, q.TrackingMethod, q.AppLabelKey, q.AppName) if err != nil { log.Warnf("manifest cache set error %s/%s: %v", q.ApplicationSource.String(), cacheKey, err) } @@ -698,10 +803,10 @@ func (s *Service) getManifestCacheEntry(cacheKey string, q *apiclient.ManifestRe if s.initConstants.PauseGenerationOnFailureForRequests > 0 && res.NumberOfCachedResponsesReturned > 0 { if res.NumberOfCachedResponsesReturned >= s.initConstants.PauseGenerationOnFailureForRequests { - cache.LogDebugManifestCacheKeyFields("deleting manifests cache", "reset after paused generation count", cacheKey, q.ApplicationSource, q, q.Namespace, q.TrackingMethod, q.AppLabelKey, q.AppName) + cache.LogDebugManifestCacheKeyFields("deleting manifests cache", "reset after paused generation count", cacheKey, q.ApplicationSource, q.RefSources, q, q.Namespace, q.TrackingMethod, q.AppLabelKey, q.AppName) // We can now try again, so reset the error cache state and run the operation below - err = s.cache.DeleteManifests(cacheKey, q.ApplicationSource, q, q.Namespace, q.TrackingMethod, q.AppLabelKey, q.AppName) + err = s.cache.DeleteManifests(cacheKey, q.ApplicationSource, q.RefSources, q, q.Namespace, q.TrackingMethod, q.AppLabelKey, q.AppName) if err != nil { log.Warnf("manifest cache set error %s/%s: %v", q.ApplicationSource.String(), cacheKey, err) } @@ -716,12 +821,12 @@ func (s *Service) getManifestCacheEntry(cacheKey string, q *apiclient.ManifestRe cachedErrorResponse := fmt.Errorf(cachedManifestGenerationPrefix+": %s", res.MostRecentError) if firstInvocation { - cache.LogDebugManifestCacheKeyFields("setting manifests cache", "update error count", cacheKey, q.ApplicationSource, q, q.Namespace, q.TrackingMethod, q.AppLabelKey, q.AppName) + cache.LogDebugManifestCacheKeyFields("setting manifests cache", "update error count", cacheKey, q.ApplicationSource, q.RefSources, q, q.Namespace, q.TrackingMethod, q.AppLabelKey, q.AppName) // Increment the number of returned cached responses and push that new value to the cache // (if we have not already done so previously in this function) res.NumberOfCachedResponsesReturned++ - err = s.cache.SetManifests(cacheKey, q.ApplicationSource, q, q.Namespace, q.TrackingMethod, q.AppLabelKey, q.AppName, &res) + err = s.cache.SetManifests(cacheKey, q.ApplicationSource, q.RefSources, q, q.Namespace, q.TrackingMethod, q.AppLabelKey, q.AppName, &res) if err != nil { log.Warnf("manifest cache set error %s/%s: %v", q.ApplicationSource.String(), cacheKey, err) } @@ -866,7 +971,7 @@ func populateRequestRepos(appPath string, q *apiclient.ManifestRequest) error { return nil } -func helmTemplate(appPath string, repoRoot string, env *v1alpha1.Env, q *apiclient.ManifestRequest, isLocal bool) ([]*unstructured.Unstructured, error) { +func helmTemplate(appPath string, repoRoot string, env *v1alpha1.Env, q *apiclient.ManifestRequest, isLocal bool, gitRepoPaths io.TempPaths) ([]*unstructured.Unstructured, error) { concurrencyAllowed := isConcurrencyAllowed(appPath) if !concurrencyAllowed { manifestGenerateLock.Lock(appPath) @@ -900,34 +1005,25 @@ func helmTemplate(appPath string, repoRoot string, env *v1alpha1.Env, q *apiclie templateOpts.Name = appHelm.ReleaseName } - for _, val := range appHelm.ValueFiles { - - // This will resolve val to an absolute path (or an URL) - path, isRemote, err := pathutil.ResolveValueFilePathOrUrl(appPath, repoRoot, env.Envsubst(val), q.GetValuesFileSchemes()) - if err != nil { - return nil, err - } - - if !isRemote { - _, err = os.Stat(string(path)) - if os.IsNotExist(err) { - if appHelm.IgnoreMissingValueFiles { - log.Debugf(" %s values file does not exist", path) - continue - } - } - } - - templateOpts.Values = append(templateOpts.Values, path) + resolvedValueFiles, err := getResolvedValueFiles(appPath, repoRoot, env, q.GetValuesFileSchemes(), appHelm.ValueFiles, q.RefSources, gitRepoPaths, appHelm.IgnoreMissingValueFiles) + if err != nil { + return nil, err } + templateOpts.Values = resolvedValueFiles + if appHelm.Values != "" { rand, err := uuid.NewRandom() if err != nil { return nil, err } p := path.Join(os.TempDir(), rand.String()) - defer func() { _ = os.RemoveAll(p) }() + defer func() { + // do not remove the directory if it is the source has Ref field set + if q.ApplicationSource.Ref == "" { + _ = os.RemoveAll(p) + } + }() err = os.WriteFile(p, []byte(appHelm.Values), 0644) if err != nil { return nil, err @@ -1006,6 +1102,84 @@ func helmTemplate(appPath string, repoRoot string, env *v1alpha1.Env, q *apiclie return kube.SplitYAML([]byte(out)) } +func getResolvedValueFiles( + appPath string, + repoRoot string, + env *v1alpha1.Env, + allowedValueFilesSchemas []string, + rawValueFiles []string, + refSources map[string]*v1alpha1.RefTarget, + gitRepoPaths io.TempPaths, + ignoreMissingValueFiles bool, +) ([]pathutil.ResolvedFilePath, error) { + var resolvedValueFiles []pathutil.ResolvedFilePath + for _, rawValueFile := range rawValueFiles { + var isRemote = false + var resolvedPath pathutil.ResolvedFilePath + var err error + + referencedSource := getReferencedSource(rawValueFile, refSources) + if referencedSource != nil { + // If the $-prefixed path appears to reference another source, do env substitution _after_ resolving that source. + resolvedPath, err = getResolvedRefValueFile(rawValueFile, env, allowedValueFilesSchemas, referencedSource.Repo.Repo, gitRepoPaths) + if err != nil { + return nil, err + } + } else { + // This will resolve val to an absolute path (or an URL) + resolvedPath, isRemote, err = pathutil.ResolveValueFilePathOrUrl(appPath, repoRoot, env.Envsubst(rawValueFile), allowedValueFilesSchemas) + if err != nil { + return nil, err + } + } + + if !isRemote { + _, err = os.Stat(string(resolvedPath)) + if os.IsNotExist(err) { + if ignoreMissingValueFiles { + log.Debugf(" %s values file does not exist", resolvedPath) + continue + } + } + } + + resolvedValueFiles = append(resolvedValueFiles, resolvedPath) + } + return resolvedValueFiles, nil +} + +func getResolvedRefValueFile( + rawValueFile string, + env *v1alpha1.Env, + allowedValueFilesSchemas []string, + refSourceRepo string, + gitRepoPaths io.TempPaths, +) (pathutil.ResolvedFilePath, error) { + pathStrings := strings.Split(rawValueFile, "/") + repoPath := gitRepoPaths.GetPathIfExists(git.NormalizeGitURL(refSourceRepo)) + if repoPath == "" { + return "", fmt.Errorf("failed to find repo %q", refSourceRepo) + } + pathStrings[0] = "" // Remove first segment. It will be inserted by pathutil.ResolveValueFilePathOrUrl. + substitutedPath := strings.Join(pathStrings, "/") + + // Resolve the path relative to the referenced repo and block any attempt at traversal. + resolvedPath, _, err := pathutil.ResolveValueFilePathOrUrl(repoPath, repoPath, env.Envsubst(substitutedPath), allowedValueFilesSchemas) + if err != nil { + return "", err + } + return resolvedPath, nil +} + +func getReferencedSource(rawValueFile string, refSources map[string]*v1alpha1.RefTarget) *v1alpha1.RefTarget { + if !strings.HasPrefix(rawValueFile, "$") { + return nil + } + refVar := strings.Split(rawValueFile, "/")[0] + referencedSource := refSources[refVar] + return referencedSource +} + func getRepoCredential(repoCredentials []*v1alpha1.RepoCreds, repoURL string) *v1alpha1.RepoCreds { for _, cred := range repoCredentials { url := strings.TrimPrefix(repoURL, ociPrefix) @@ -1048,7 +1222,7 @@ func WithCMPTarExcludedGlobs(excludedGlobs []string) GenerateManifestOpt { } // GenerateManifests generates manifests from a path. Overrides are applied as a side effect on the given ApplicationSource. -func GenerateManifests(ctx context.Context, appPath, repoRoot, revision string, q *apiclient.ManifestRequest, isLocal bool, gitCredsStore git.CredsStore, maxCombinedManifestQuantity resource.Quantity, opts ...GenerateManifestOpt) (*apiclient.ManifestResponse, error) { +func GenerateManifests(ctx context.Context, appPath, repoRoot, revision string, q *apiclient.ManifestRequest, isLocal bool, gitCredsStore git.CredsStore, maxCombinedManifestQuantity resource.Quantity, gitRepoPaths io.TempPaths, opts ...GenerateManifestOpt) (*apiclient.ManifestResponse, error) { opt := newGenerateManifestOpt(opts...) var targetObjs []*unstructured.Unstructured var dest *v1alpha1.ApplicationDestination @@ -1067,7 +1241,7 @@ func GenerateManifests(ctx context.Context, appPath, repoRoot, revision string, switch appSourceType { case v1alpha1.ApplicationSourceTypeHelm: - targetObjs, err = helmTemplate(appPath, repoRoot, env, q, isLocal) + targetObjs, err = helmTemplate(appPath, repoRoot, env, q, isLocal, gitRepoPaths) case v1alpha1.ApplicationSourceTypeKustomize: kustomizeBinary := "" if q.KustomizeOptions != nil { @@ -1735,7 +1909,7 @@ func (s *Service) GetAppDetails(ctx context.Context, q *apiclient.RepoServerAppD switch appSourceType { case v1alpha1.ApplicationSourceTypeHelm: - if err := populateHelmAppDetails(res, opContext.appPath, repoRoot, q); err != nil { + if err := populateHelmAppDetails(res, opContext.appPath, repoRoot, q, s.gitRepoPaths); err != nil { return err } case v1alpha1.ApplicationSourceTypeKustomize: @@ -1747,19 +1921,19 @@ func (s *Service) GetAppDetails(ctx context.Context, q *apiclient.RepoServerAppD return fmt.Errorf("failed to populate plugin app details: %w", err) } } - _ = s.cache.SetAppDetails(revision, q.Source, res, v1alpha1.TrackingMethod(q.TrackingMethod)) + _ = s.cache.SetAppDetails(revision, q.Source, q.RefSources, res, v1alpha1.TrackingMethod(q.TrackingMethod)) return nil } settings := operationSettings{allowConcurrent: q.Source.AllowsConcurrentProcessing(), noCache: q.NoCache, noRevisionCache: q.NoCache || q.NoRevisionCache} - err := s.runRepoOperation(ctx, q.Source.TargetRevision, q.Repo, q.Source, false, cacheFn, operation, settings) + err := s.runRepoOperation(ctx, q.Source.TargetRevision, q.Repo, q.Source, false, cacheFn, operation, settings, false) return res, err } func (s *Service) createGetAppDetailsCacheHandler(res *apiclient.RepoAppDetailsResponse, q *apiclient.RepoServerAppDetailsQuery) func(revision string, _ bool) (bool, error) { return func(revision string, _ bool) (bool, error) { - err := s.cache.GetAppDetails(revision, q.Source, res, v1alpha1.TrackingMethod(q.TrackingMethod)) + err := s.cache.GetAppDetails(revision, q.Source, q.RefSources, res, v1alpha1.TrackingMethod(q.TrackingMethod)) if err == nil { log.Infof("app details cache hit: %s/%s", revision, q.Source.Path) return true, nil @@ -1774,7 +1948,7 @@ func (s *Service) createGetAppDetailsCacheHandler(res *apiclient.RepoAppDetailsR } } -func populateHelmAppDetails(res *apiclient.RepoAppDetailsResponse, appPath string, repoRoot string, q *apiclient.RepoServerAppDetailsQuery) error { +func populateHelmAppDetails(res *apiclient.RepoAppDetailsResponse, appPath string, repoRoot string, q *apiclient.RepoServerAppDetailsQuery, gitRepoPaths io.TempPaths) error { var selectedValueFiles []string if q.Source.Helm != nil { @@ -1812,14 +1986,13 @@ func populateHelmAppDetails(res *apiclient.RepoAppDetailsResponse, appPath strin } else { log.Warnf("Values file %s is not allowed: %v", filepath.Join(appPath, "values.yaml"), err) } - var resolvedSelectedValueFiles []pathutil.ResolvedFilePath - // drop not allowed values files - for _, file := range selectedValueFiles { - if resolvedFile, _, err := pathutil.ResolveValueFilePathOrUrl(appPath, repoRoot, file, q.GetValuesFileSchemes()); err == nil { - resolvedSelectedValueFiles = append(resolvedSelectedValueFiles, resolvedFile) - } else { - log.Warnf("Values file %s is not allowed: %v", file, err) - } + ignoreMissingValueFiles := false + if q.Source.Helm != nil { + ignoreMissingValueFiles = q.Source.Helm.IgnoreMissingValueFiles + } + resolvedSelectedValueFiles, err := getResolvedValueFiles(appPath, repoRoot, &v1alpha1.Env{}, q.GetValuesFileSchemes(), selectedValueFiles, q.RefSources, gitRepoPaths, ignoreMissingValueFiles) + if err != nil { + return fmt.Errorf("failed to resolve value files: %w", err) } params, err := h.GetParameters(resolvedSelectedValueFiles, appPath, repoRoot) if err != nil { @@ -2213,8 +2386,9 @@ func (s *Service) ResolveRevision(ctx context.Context, q *apiclient.ResolveRevis app := q.App ambiguousRevision := q.AmbiguousRevision var revision string - if app.Spec.Source.IsHelm() { - _, revision, err := s.newHelmClientResolveRevision(repo, ambiguousRevision, app.Spec.Source.Chart, true) + var source = app.Spec.GetSource() + if source.IsHelm() { + _, revision, err := s.newHelmClientResolveRevision(repo, ambiguousRevision, source.Chart, true) if err != nil { return &apiclient.ResolveRevisionResponse{Revision: "", AmbiguousRevision: ""}, err diff --git a/reposerver/repository/repository.proto b/reposerver/repository/repository.proto index d2610d600a87a..c5212265d33b7 100644 --- a/reposerver/repository/repository.proto +++ b/reposerver/repository/repository.proto @@ -29,6 +29,8 @@ message ManifestRequest { string trackingMethod = 19; map enabledSourceTypes = 20; github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.HelmOptions helmOptions = 21; + bool hasMultipleSources = 22; + map refSources = 23; } message ManifestRequestWithFiles { @@ -129,6 +131,7 @@ message RepoServerAppDetailsQuery { string trackingMethod = 8; map enabledSourceTypes = 9; github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.HelmOptions helmOptions = 10; + map refSources = 11; } // RepoAppDetailsResponse application details diff --git a/reposerver/repository/repository_test.go b/reposerver/repository/repository_test.go index ef1d4a2ed766a..d8f1df05f44c3 100644 --- a/reposerver/repository/repository_test.go +++ b/reposerver/repository/repository_test.go @@ -35,11 +35,13 @@ import ( fileutil "github.com/argoproj/argo-cd/v2/test/fixture/path" "github.com/argoproj/argo-cd/v2/util/argo" cacheutil "github.com/argoproj/argo-cd/v2/util/cache" + dbmocks "github.com/argoproj/argo-cd/v2/util/db/mocks" "github.com/argoproj/argo-cd/v2/util/git" gitmocks "github.com/argoproj/argo-cd/v2/util/git/mocks" "github.com/argoproj/argo-cd/v2/util/helm" helmmocks "github.com/argoproj/argo-cd/v2/util/helm/mocks" "github.com/argoproj/argo-cd/v2/util/io" + iomocks "github.com/argoproj/argo-cd/v2/util/io/mocks" ) const testSignature = `gpg: Signature made Wed Feb 26 23:22:34 2020 CET @@ -47,14 +49,14 @@ gpg: using RSA key 4AEE18F83AFDEB23 gpg: Good signature from "GitHub (web-flow commit signing) " [ultimate] ` -type clientFunc func(*gitmocks.Client, *helmmocks.Client) +type clientFunc func(*gitmocks.Client, *helmmocks.Client, *iomocks.TempPaths) func newServiceWithMocks(root string, signed bool) (*Service, *gitmocks.Client) { root, err := filepath.Abs(root) if err != nil { panic(err) } - return newServiceWithOpt(func(gitClient *gitmocks.Client, helmClient *helmmocks.Client) { + return newServiceWithOpt(func(gitClient *gitmocks.Client, helmClient *helmmocks.Client, paths *iomocks.TempPaths) { gitClient.On("Init").Return(nil) gitClient.On("Fetch", mock.Anything).Return(nil) gitClient.On("Checkout", mock.Anything, mock.Anything).Return(nil) @@ -79,13 +81,18 @@ func newServiceWithMocks(root string, signed bool) (*Service, *gitmocks.Client) helmClient.On("CleanChartCache", chart, version).Return(nil) helmClient.On("CleanChartCache", oobChart, version).Return(nil) helmClient.On("DependencyBuild").Return(nil) + + paths.On("Add", mock.Anything, mock.Anything).Return(root, nil) + paths.On("GetPath", mock.Anything).Return(root, nil) + paths.On("GetPathIfExists", mock.Anything).Return(root, nil) }, root) } func newServiceWithOpt(cf clientFunc, root string) (*Service, *gitmocks.Client) { helmClient := &helmmocks.Client{} gitClient := &gitmocks.Client{} - cf(gitClient, helmClient) + paths := &iomocks.TempPaths{} + cf(gitClient, helmClient, paths) service := NewService(metrics.NewMetricsServer(), cache.NewCache( cacheutil.NewCache(cacheutil.NewInMemoryCache(1*time.Minute)), 1*time.Minute, @@ -101,6 +108,7 @@ func newServiceWithOpt(cf clientFunc, root string) (*Service, *gitmocks.Client) service.gitRepoInitializer = func(rootPath string) goio.Closer { return io.NopCloser } + service.gitRepoPaths = paths return service, gitClient } @@ -122,13 +130,15 @@ func newServiceWithCommitSHA(root, revision string) *Service { revisionErr = errors.New("not a commit SHA") } - service, gitClient := newServiceWithOpt(func(gitClient *gitmocks.Client, helmClient *helmmocks.Client) { + service, gitClient := newServiceWithOpt(func(gitClient *gitmocks.Client, helmClient *helmmocks.Client, paths *iomocks.TempPaths) { gitClient.On("Init").Return(nil) gitClient.On("Fetch", mock.Anything).Return(nil) gitClient.On("Checkout", mock.Anything, mock.Anything).Return(nil) gitClient.On("LsRemote", revision).Return(revision, revisionErr) gitClient.On("CommitSHA").Return("632039659e542ed7de0c170a4fcc1c571b288fc0", nil) gitClient.On("Root").Return(root) + paths.On("GetPath", mock.Anything).Return(root, nil) + paths.On("GetPathIfExists", mock.Anything).Return(root, nil) }, root) service.newGitClient = func(rawRepoURL string, root string, creds git.Creds, insecure bool, enableLfs bool, proxy string, opts ...git.ClientOpts) (client git.Client, e error) { @@ -153,7 +163,7 @@ func TestGenerateYamlManifestInDir(t *testing.T) { assert.Equal(t, countOfManifests, len(res1.Manifests)) // this will test concatenated manifests to verify we split YAMLs correctly - res2, err := GenerateManifests(context.Background(), "./testdata/concatenated", "/", "", &q, false, &git.NoopCredsStore{}, resource.MustParse("0")) + res2, err := GenerateManifests(context.Background(), "./testdata/concatenated", "/", "", &q, false, &git.NoopCredsStore{}, resource.MustParse("0"), nil) assert.NoError(t, err) assert.Equal(t, 3, len(res2.Manifests)) } @@ -209,7 +219,7 @@ func Test_GenerateManifests_NoOutOfBoundsAccess(t *testing.T) { } q := apiclient.ManifestRequest{Repo: &argoappv1.Repository{}, ApplicationSource: &argoappv1.ApplicationSource{}} - res, err := GenerateManifests(context.Background(), repoDir, "", "", &q, false, &git.NoopCredsStore{}, resource.MustParse("0")) + res, err := GenerateManifests(context.Background(), repoDir, "", "", &q, false, &git.NoopCredsStore{}, resource.MustParse("0"), nil) require.Error(t, err) assert.NotContains(t, err.Error(), mustNotContain) assert.Contains(t, err.Error(), "illegal filepath") @@ -224,7 +234,7 @@ func TestGenerateManifests_MissingSymlinkDestination(t *testing.T) { require.NoError(t, err) q := apiclient.ManifestRequest{Repo: &argoappv1.Repository{}, ApplicationSource: &argoappv1.ApplicationSource{}} - _, err = GenerateManifests(context.Background(), repoDir, "", "", &q, false, &git.NoopCredsStore{}, resource.MustParse("0")) + _, err = GenerateManifests(context.Background(), repoDir, "", "", &q, false, &git.NoopCredsStore{}, resource.MustParse("0"), nil) require.NoError(t, err) } @@ -239,7 +249,7 @@ func TestGenerateManifests_K8SAPIResetCache(t *testing.T) { cachedFakeResponse := &apiclient.ManifestResponse{Manifests: []string{"Fake"}} - err := service.cache.SetManifests(mock.Anything, &src, &q, "", "", "", "", &cache.CachedManifestResponse{ManifestResponse: cachedFakeResponse}) + err := service.cache.SetManifests(mock.Anything, &src, q.RefSources, &q, "", "", "", "", &cache.CachedManifestResponse{ManifestResponse: cachedFakeResponse}) assert.NoError(t, err) res, err := service.GenerateManifest(context.Background(), &q) @@ -261,7 +271,7 @@ func TestGenerateManifests_EmptyCache(t *testing.T) { Repo: &argoappv1.Repository{}, ApplicationSource: &src, } - err := service.cache.SetManifests(mock.Anything, &src, &q, "", "", "", "", &cache.CachedManifestResponse{ManifestResponse: nil}) + err := service.cache.SetManifests(mock.Anything, &src, q.RefSources, &q, "", "", "", "", &cache.CachedManifestResponse{ManifestResponse: nil}) assert.NoError(t, err) res, err := service.GenerateManifest(context.Background(), &q) @@ -286,6 +296,69 @@ func TestHelmManifestFromChartRepo(t *testing.T) { }, response) } +func TestHelmChartReferencingExternalValues(t *testing.T) { + service := newService(".") + spec := argoappv1.ApplicationSpec{ + Sources: []argoappv1.ApplicationSource{ + {RepoURL: "https://helm.example.com", Chart: "my-chart", TargetRevision: ">= 1.0.0", Helm: &argoappv1.ApplicationSourceHelm{ + ValueFiles: []string{"$ref/testdata/my-chart/my-chart-values.yaml"}, + }}, + {Ref: "ref", RepoURL: "https://git.example.com/test/repo"}, + }, + } + repoDB := &dbmocks.ArgoDB{} + repoDB.On("GetRepository", context.Background(), "https://git.example.com/test/repo").Return(&argoappv1.Repository{ + Repo: "https://git.example.com/test/repo", + }, nil) + refSources, err := argo.GetRefSources(context.Background(), spec, repoDB) + require.NoError(t, err) + request := &apiclient.ManifestRequest{Repo: &argoappv1.Repository{}, ApplicationSource: &spec.Sources[0], NoCache: true, RefSources: refSources, HasMultipleSources: true} + response, err := service.GenerateManifest(context.Background(), request) + assert.NoError(t, err) + assert.NotNil(t, response) + assert.Equal(t, &apiclient.ManifestResponse{ + Manifests: []string{"{\"apiVersion\":\"v1\",\"kind\":\"ConfigMap\",\"metadata\":{\"name\":\"my-map\"}}"}, + Namespace: "", + Server: "", + Revision: "1.1.0", + SourceType: "Helm", + }, response) +} + +func TestHelmChartReferencingExternalValues_OutOfBounds_Symlink(t *testing.T) { + service := newService(".") + err := os.Mkdir("testdata/oob-symlink", 0755) + require.NoError(t, err) + t.Cleanup(func() { + err = os.RemoveAll("testdata/oob-symlink") + require.NoError(t, err) + }) + // Create a symlink to a file outside of the repo + err = os.Symlink("../../../values.yaml", "./testdata/oob-symlink/oob-symlink.yaml") + // Create a regular file to reference from another source + err = os.WriteFile("./testdata/oob-symlink/values.yaml", []byte("foo: bar"), 0644) + require.NoError(t, err) + spec := argoappv1.ApplicationSpec{ + Sources: []argoappv1.ApplicationSource{ + {RepoURL: "https://helm.example.com", Chart: "my-chart", TargetRevision: ">= 1.0.0", Helm: &argoappv1.ApplicationSourceHelm{ + // Reference `ref` but do not use the oob symlink. The mere existence of the link should be enough to + // cause an error. + ValueFiles: []string{"$ref/testdata/oob-symlink/values.yaml"}, + }}, + {Ref: "ref", RepoURL: "https://git.example.com/test/repo"}, + }, + } + repoDB := &dbmocks.ArgoDB{} + repoDB.On("GetRepository", context.Background(), "https://git.example.com/test/repo").Return(&argoappv1.Repository{ + Repo: "https://git.example.com/test/repo", + }, nil) + refSources, err := argo.GetRefSources(context.Background(), spec, repoDB) + require.NoError(t, err) + request := &apiclient.ManifestRequest{Repo: &argoappv1.Repository{}, ApplicationSource: &spec.Sources[0], NoCache: true, RefSources: refSources, HasMultipleSources: true} + _, err = service.GenerateManifest(context.Background(), request) + assert.Error(t, err) +} + func TestGenerateManifestsUseExactRevision(t *testing.T) { service, gitClient := newServiceWithMocks(".", false) @@ -391,7 +464,7 @@ func TestManifestGenErrorCacheByNumRequests(t *testing.T) { assert.NotNil(t, manifestRequest) cachedManifestResponse := &cache.CachedManifestResponse{} - err := service.cache.GetManifests(mock.Anything, manifestRequest.ApplicationSource, manifestRequest, manifestRequest.Namespace, "", manifestRequest.AppLabelKey, manifestRequest.AppName, cachedManifestResponse) + err := service.cache.GetManifests(mock.Anything, manifestRequest.ApplicationSource, manifestRequest.RefSources, manifestRequest, manifestRequest.Namespace, "", manifestRequest.AppLabelKey, manifestRequest.AppName, cachedManifestResponse) assert.Nil(t, err) return cachedManifestResponse } @@ -1081,28 +1154,37 @@ func TestGenerateHelmWithFileParameter(t *testing.T) { func TestGenerateNullList(t *testing.T) { service := newService(".") - res1, err := service.GenerateManifest(context.Background(), &apiclient.ManifestRequest{ - Repo: &argoappv1.Repository{}, - ApplicationSource: &argoappv1.ApplicationSource{Path: "./testdata/null-list"}, + t.Run("null list", func(t *testing.T) { + res1, err := service.GenerateManifest(context.Background(), &apiclient.ManifestRequest{ + Repo: &argoappv1.Repository{}, + ApplicationSource: &argoappv1.ApplicationSource{Path: "./testdata/null-list"}, + NoCache: true, + }) + assert.Nil(t, err) + assert.Equal(t, len(res1.Manifests), 1) + assert.Contains(t, res1.Manifests[0], "prometheus-operator-operator") }) - assert.Nil(t, err) - assert.Equal(t, len(res1.Manifests), 1) - assert.Contains(t, res1.Manifests[0], "prometheus-operator-operator") - res1, err = service.GenerateManifest(context.Background(), &apiclient.ManifestRequest{ - Repo: &argoappv1.Repository{}, - ApplicationSource: &argoappv1.ApplicationSource{Path: "./testdata/empty-list"}, + t.Run("empty list", func(t *testing.T) { + res1, err := service.GenerateManifest(context.Background(), &apiclient.ManifestRequest{ + Repo: &argoappv1.Repository{}, + ApplicationSource: &argoappv1.ApplicationSource{Path: "./testdata/empty-list"}, + NoCache: true, + }) + assert.Nil(t, err) + assert.Equal(t, len(res1.Manifests), 1) + assert.Contains(t, res1.Manifests[0], "prometheus-operator-operator") }) - assert.Nil(t, err) - assert.Equal(t, len(res1.Manifests), 1) - assert.Contains(t, res1.Manifests[0], "prometheus-operator-operator") - res1, err = service.GenerateManifest(context.Background(), &apiclient.ManifestRequest{ - Repo: &argoappv1.Repository{}, - ApplicationSource: &argoappv1.ApplicationSource{Path: "./testdata/weird-list"}, + t.Run("weird list", func(t *testing.T) { + res1, err := service.GenerateManifest(context.Background(), &apiclient.ManifestRequest{ + Repo: &argoappv1.Repository{}, + ApplicationSource: &argoappv1.ApplicationSource{Path: "./testdata/weird-list"}, + NoCache: true, + }) + assert.Nil(t, err) + assert.Len(t, res1.Manifests, 2) }) - assert.Nil(t, err) - assert.Equal(t, 2, len(res1.Manifests)) } func TestIdentifyAppSourceTypeByAppDirWithKustomizations(t *testing.T) { @@ -1167,7 +1249,7 @@ func TestGenerateFromUTF16(t *testing.T) { Repo: &argoappv1.Repository{}, ApplicationSource: &argoappv1.ApplicationSource{}, } - res1, err := GenerateManifests(context.Background(), "./testdata/utf-16", "/", "", &q, false, &git.NoopCredsStore{}, resource.MustParse("0")) + res1, err := GenerateManifests(context.Background(), "./testdata/utf-16", "/", "", &q, false, &git.NoopCredsStore{}, resource.MustParse("0"), nil) assert.Nil(t, err) assert.Equal(t, 2, len(res1.Manifests)) } @@ -1661,7 +1743,7 @@ func TestGenerateManifestsWithAppParameterFile(t *testing.T) { // Try to pull from the cache with a `source` that does not include any overrides. Overrides should not be // part of the cache key, because you can't get the overrides without a repo operation. And avoiding repo // operations is the point of the cache. - err = service.cache.GetManifests(mock.Anything, source, &argoappv1.ClusterInfo{}, "", "", "", "test", res) + err = service.cache.GetManifests(mock.Anything, source, argoappv1.RefTargetRevisionMapping{}, &argoappv1.ClusterInfo{}, "", "", "", "test", res) assert.NoError(t, err) }) }) @@ -2318,7 +2400,7 @@ func TestResolveRevision(t *testing.T) { service := newService(".") repo := &argoappv1.Repository{Repo: "https://github.com/argoproj/argo-cd"} - app := &argoappv1.Application{} + app := &argoappv1.Application{Spec: argoappv1.ApplicationSpec{Source: &argoappv1.ApplicationSource{}}} resolveRevisionResponse, err := service.ResolveRevision(context.Background(), &apiclient.ResolveRevisionRequest{ Repo: repo, App: app, @@ -2340,7 +2422,7 @@ func TestResolveRevisionNegativeScenarios(t *testing.T) { service := newService(".") repo := &argoappv1.Repository{Repo: "https://github.com/argoproj/argo-cd"} - app := &argoappv1.Application{} + app := &argoappv1.Application{Spec: argoappv1.ApplicationSpec{Source: &argoappv1.ApplicationSource{}}} resolveRevisionResponse, err := service.ResolveRevision(context.Background(), &apiclient.ResolveRevisionRequest{ Repo: repo, App: app, @@ -2417,11 +2499,7 @@ func TestInit(t *testing.T) { require.NoError(t, service.Init()) - repo1Path, err := service.gitRepoPaths.GetPath(git.NormalizeGitURL("https://github.com/argo-cd/test-repo1")) - assert.NoError(t, err) - assert.Equal(t, repoPath, repo1Path) - - _, err = os.ReadDir(dir) + _, err := os.ReadDir(dir) require.Error(t, err) require.NoError(t, initGitRepo(path.Join(dir, "repo2"), "https://github.com/argo-cd/test-repo2")) } @@ -2487,6 +2565,7 @@ func Test_findHelmValueFilesInPath(t *testing.T) { } func Test_populateHelmAppDetails(t *testing.T) { + var emptyTempPaths = io.NewRandomizedTempPaths(t.TempDir()) res := apiclient.RepoAppDetailsResponse{} q := apiclient.RepoServerAppDetailsQuery{ Repo: &argoappv1.Repository{}, @@ -2496,17 +2575,18 @@ func Test_populateHelmAppDetails(t *testing.T) { } appPath, err := filepath.Abs("./testdata/values-files/") require.NoError(t, err) - err = populateHelmAppDetails(&res, appPath, appPath, &q) + err = populateHelmAppDetails(&res, appPath, appPath, &q, emptyTempPaths) require.NoError(t, err) assert.Len(t, res.Helm.Parameters, 3) assert.Len(t, res.Helm.ValueFiles, 4) } func Test_populateHelmAppDetails_values_symlinks(t *testing.T) { + var emptyTempPaths = io.NewRandomizedTempPaths(t.TempDir()) t.Run("inbound", func(t *testing.T) { res := apiclient.RepoAppDetailsResponse{} q := apiclient.RepoServerAppDetailsQuery{Repo: &argoappv1.Repository{}, Source: &argoappv1.ApplicationSource{}} - err := populateHelmAppDetails(&res, "./testdata/in-bounds-values-file-link/", "./testdata/in-bounds-values-file-link/", &q) + err := populateHelmAppDetails(&res, "./testdata/in-bounds-values-file-link/", "./testdata/in-bounds-values-file-link/", &q, emptyTempPaths) require.NoError(t, err) assert.NotEmpty(t, res.Helm.Values) assert.NotEmpty(t, res.Helm.Parameters) @@ -2515,7 +2595,7 @@ func Test_populateHelmAppDetails_values_symlinks(t *testing.T) { t.Run("out of bounds", func(t *testing.T) { res := apiclient.RepoAppDetailsResponse{} q := apiclient.RepoServerAppDetailsQuery{Repo: &argoappv1.Repository{}, Source: &argoappv1.ApplicationSource{}} - err := populateHelmAppDetails(&res, "./testdata/out-of-bounds-values-file-link/", "./testdata/out-of-bounds-values-file-link/", &q) + err := populateHelmAppDetails(&res, "./testdata/out-of-bounds-values-file-link/", "./testdata/out-of-bounds-values-file-link/", &q, emptyTempPaths) require.NoError(t, err) assert.Empty(t, res.Helm.Values) assert.Empty(t, res.Helm.Parameters) @@ -2536,3 +2616,159 @@ func TestOCIDependencies(t *testing.T) { assert.Equal(t, q.Repos[0].EnableOCI, true) assert.Equal(t, q.Repos[0].Repo, "example.com") } + +func Test_getResolvedValueFiles(t *testing.T) { + tempDir := t.TempDir() + paths := io.NewRandomizedTempPaths(tempDir) + paths.Add(git.NormalizeGitURL("https://github.com/org/repo1"), path.Join(tempDir, "repo1")) + + testCases := []struct { + name string + rawPath string + env *argoappv1.Env + refSources map[string]*argoappv1.RefTarget + expectedPath string + expectedErr bool + }{ + { + name: "simple path", + rawPath: "values.yaml", + env: &argoappv1.Env{}, + refSources: map[string]*argoappv1.RefTarget{}, + expectedPath: path.Join(tempDir, "main-repo", "values.yaml"), + }, + { + name: "simple ref", + rawPath: "$ref/values.yaml", + env: &argoappv1.Env{}, + refSources: map[string]*argoappv1.RefTarget{ + "$ref": { + Repo: argoappv1.Repository{ + Repo: "https://github.com/org/repo1", + }, + }, + }, + expectedPath: path.Join(tempDir, "repo1", "values.yaml"), + }, + { + name: "only ref", + rawPath: "$ref", + env: &argoappv1.Env{}, + refSources: map[string]*argoappv1.RefTarget{ + "$ref": { + Repo: argoappv1.Repository{ + Repo: "https://github.com/org/repo1", + }, + }, + }, + expectedErr: true, + }, + { + name: "attempted traversal", + rawPath: "$ref/../values.yaml", + env: &argoappv1.Env{}, + refSources: map[string]*argoappv1.RefTarget{ + "$ref": { + Repo: argoappv1.Repository{ + Repo: "https://github.com/org/repo1", + }, + }, + }, + expectedErr: true, + }, + { + // Since $ref doesn't resolve to a ref target, we assume it's an env var. Since the env var isn't specified, + // it's replaced with an empty string. This is necessary for backwards compatibility with behavior before + // ref targets were introduced. + name: "ref doesn't exist", + rawPath: "$ref/values.yaml", + env: &argoappv1.Env{}, + refSources: map[string]*argoappv1.RefTarget{}, + expectedPath: path.Join(tempDir, "main-repo", "values.yaml"), + }, + { + name: "repo doesn't exist", + rawPath: "$ref/values.yaml", + env: &argoappv1.Env{}, + refSources: map[string]*argoappv1.RefTarget{ + "$ref": { + Repo: argoappv1.Repository{ + Repo: "https://github.com/org/repo2", + }, + }, + }, + expectedErr: true, + }, + { + name: "env var is resolved", + rawPath: "$ref/$APP_PATH/values.yaml", + env: &argoappv1.Env{ + &argoappv1.EnvEntry{ + Name: "APP_PATH", + Value: "app-path", + }, + }, + refSources: map[string]*argoappv1.RefTarget{ + "$ref": { + Repo: argoappv1.Repository{ + Repo: "https://github.com/org/repo1", + }, + }, + }, + expectedPath: path.Join(tempDir, "repo1", "app-path", "values.yaml"), + }, + { + name: "traversal in env var is blocked", + rawPath: "$ref/$APP_PATH/values.yaml", + env: &argoappv1.Env{ + &argoappv1.EnvEntry{ + Name: "APP_PATH", + Value: "..", + }, + }, + refSources: map[string]*argoappv1.RefTarget{ + "$ref": { + Repo: argoappv1.Repository{ + Repo: "https://github.com/org/repo1", + }, + }, + }, + expectedErr: true, + }, + { + name: "env var prefix", + rawPath: "$APP_PATH/values.yaml", + env: &argoappv1.Env{ + &argoappv1.EnvEntry{ + Name: "APP_PATH", + Value: "app-path", + }, + }, + refSources: map[string]*argoappv1.RefTarget{}, + expectedPath: path.Join(tempDir, "main-repo", "app-path", "values.yaml"), + }, + { + name: "unresolved env var", + rawPath: "$APP_PATH/values.yaml", + env: &argoappv1.Env{}, + refSources: map[string]*argoappv1.RefTarget{}, + expectedPath: path.Join(tempDir, "main-repo", "values.yaml"), + }, + } + + for _, tc := range testCases { + tcc := tc + t.Run(tcc.name, func(t *testing.T) { + t.Parallel() + resolvedPaths, err := getResolvedValueFiles(path.Join(tempDir, "main-repo"), path.Join(tempDir, "main-repo"), tcc.env, []string{}, []string{tcc.rawPath}, tcc.refSources, paths, false) + if !tcc.expectedErr { + assert.NoError(t, err) + require.Len(t, resolvedPaths, 1) + assert.Equal(t, tcc.expectedPath, string(resolvedPaths[0])) + } else { + assert.Error(t, err) + assert.Empty(t, resolvedPaths) + } + }) + } +} diff --git a/server/application/application.go b/server/application/application.go index b56db0941733e..5a06315811e52 100644 --- a/server/application/application.go +++ b/server/application/application.go @@ -215,10 +215,10 @@ func (s *Server) Create(ctx context.Context, q *application.ApplicationCreateReq created, err := s.appclientset.ArgoprojV1alpha1().Applications(appNs).Create(ctx, a, metav1.CreateOptions{}) if err == nil { - if a.Spec.Source.Plugin != nil && a.Spec.Source.Plugin.Name != "" { + if a.Spec.GetSource().Plugin != nil && a.Spec.GetSource().Plugin.Name != "" { log.WithFields(map[string]interface{}{ "application": a.Name, - "plugin": a.Spec.Source.Plugin.Name, + "plugin": a.Spec.GetSource().Plugin.Name, }).Warnf(argocommon.ConfigMapPluginDeprecationWarning) } @@ -271,7 +271,7 @@ func (s *Server) queryRepoServer(ctx context.Context, a *appv1.Application, acti return fmt.Errorf("error creating repo server client: %w", err) } defer ioutil.Close(closer) - repo, err := s.db.GetRepository(ctx, a.Spec.Source.RepoURL) + repo, err := s.db.GetRepository(ctx, a.Spec.GetSource().RepoURL) if err != nil { return fmt.Errorf("error getting repository: %w", err) } @@ -279,7 +279,7 @@ func (s *Server) queryRepoServer(ctx context.Context, a *appv1.Application, acti if err != nil { return fmt.Errorf("error getting kustomize settings: %w", err) } - kustomizeOptions, err := kustomizeSettings.GetOptions(a.Spec.Source) + kustomizeOptions, err := kustomizeSettings.GetOptions(a.Spec.GetSource()) if err != nil { return fmt.Errorf("error getting kustomize settings options: %w", err) } @@ -334,10 +334,11 @@ func (s *Server) GetManifests(ctx context.Context, q *application.ApplicationMan return nil, err } - if a.Spec.Source.Plugin != nil && a.Spec.Source.Plugin.Name != "" { + source := a.Spec.GetSource() + if source.Plugin != nil && source.Plugin.Name != "" { log.WithFields(map[string]interface{}{ "application": a.Name, - "plugin": a.Spec.Source.Plugin.Name, + "plugin": source.Plugin.Name, }).Warnf(argocommon.ConfigMapPluginDeprecationWarning) } @@ -348,7 +349,7 @@ func (s *Server) GetManifests(ctx context.Context, q *application.ApplicationMan var manifestInfo *apiclient.ManifestResponse err = s.queryRepoServer(ctx, a, func( client apiclient.RepoServerServiceClient, repo *appv1.Repository, helmRepos []*appv1.Repository, helmCreds []*appv1.RepoCreds, helmOptions *appv1.HelmOptions, kustomizeOptions *appv1.KustomizeOptions, enableGenerateManifests map[string]bool) error { - revision := a.Spec.Source.TargetRevision + revision := source.TargetRevision if q.GetRevision() != "" { revision = q.GetRevision() } @@ -382,7 +383,7 @@ func (s *Server) GetManifests(ctx context.Context, q *application.ApplicationMan AppLabelKey: appInstanceLabelKey, AppName: a.InstanceName(s.ns), Namespace: a.Spec.Destination.Namespace, - ApplicationSource: &a.Spec.Source, + ApplicationSource: &source, Repos: helmRepos, Plugins: plugins, KustomizeOptions: kustomizeOptions, @@ -476,13 +477,14 @@ func (s *Server) GetManifestsWithFiles(stream application.ApplicationService_Get return fmt.Errorf("error getting API resources: %w", err) } + source := a.Spec.GetSource() req := &apiclient.ManifestRequest{ Repo: repo, - Revision: a.Spec.Source.TargetRevision, + Revision: source.TargetRevision, AppLabelKey: appInstanceLabelKey, AppName: a.Name, Namespace: a.Spec.Destination.Namespace, - ApplicationSource: &a.Spec.Source, + ApplicationSource: &source, Repos: helmRepos, Plugins: plugins, KustomizeOptions: kustomizeOptions, @@ -559,10 +561,10 @@ func (s *Server) Get(ctx context.Context, q *application.ApplicationQuery) (*app return nil, err } - if a.Spec.Source.Plugin != nil && a.Spec.Source.Plugin.Name != "" { + if a.Spec.GetSource().Plugin != nil && a.Spec.GetSource().Plugin.Name != "" { log.WithFields(map[string]interface{}{ "application": a.Name, - "plugin": a.Spec.Source.Plugin.Name, + "plugin": a.Spec.GetSource().Plugin.Name, }).Warnf(argocommon.ConfigMapPluginDeprecationWarning) } @@ -601,9 +603,10 @@ func (s *Server) Get(ctx context.Context, q *application.ApplicationQuery) (*app kustomizeOptions *appv1.KustomizeOptions, enabledSourceTypes map[string]bool, ) error { + source := app.Spec.GetSource() _, err := client.GetAppDetails(ctx, &apiclient.RepoServerAppDetailsQuery{ Repo: repo, - Source: &app.Spec.Source, + Source: &source, AppName: appName, KustomizeOptions: kustomizeOptions, Repos: helmRepos, @@ -653,10 +656,10 @@ func (s *Server) ListResourceEvents(ctx context.Context, q *application.Applicat return nil, err } - if a.Spec.Source.Plugin != nil && a.Spec.Source.Plugin.Name != "" { + if a.Spec.GetSource().Plugin != nil && a.Spec.GetSource().Plugin.Name != "" { log.WithFields(map[string]interface{}{ "application": a.Name, - "plugin": a.Spec.Source.Plugin.Name, + "plugin": a.Spec.GetSource().Plugin.Name, }).Warnf(argocommon.ConfigMapPluginDeprecationWarning) } @@ -826,10 +829,10 @@ func (s *Server) Update(ctx context.Context, q *application.ApplicationUpdateReq return nil, err } - if a.Spec.Source.Plugin != nil && a.Spec.Source.Plugin.Name != "" { + if a.Spec.GetSource().Plugin != nil && a.Spec.GetSource().Plugin.Name != "" { log.WithFields(map[string]interface{}{ "application": a.Name, - "plugin": a.Spec.Source.Plugin.Name, + "plugin": a.Spec.GetSource().Plugin.Name, }).Warnf(argocommon.ConfigMapPluginDeprecationWarning) } @@ -855,10 +858,10 @@ func (s *Server) UpdateSpec(ctx context.Context, q *application.ApplicationUpdat return nil, err } - if a.Spec.Source.Plugin != nil && a.Spec.Source.Plugin.Name != "" { + if a.Spec.GetSource().Plugin != nil && a.Spec.GetSource().Plugin.Name != "" { log.WithFields(map[string]interface{}{ "application": a.Name, - "plugin": a.Spec.Source.Plugin.Name, + "plugin": a.Spec.GetSource().Plugin.Name, }).Warnf(argocommon.ConfigMapPluginDeprecationWarning) } @@ -887,10 +890,10 @@ func (s *Server) Patch(ctx context.Context, q *application.ApplicationPatchReque return nil, err } - if app.Spec.Source.Plugin != nil && app.Spec.Source.Plugin.Name != "" { + if app.Spec.GetSource().Plugin != nil && app.Spec.GetSource().Plugin.Name != "" { log.WithFields(map[string]interface{}{ "application": app.Name, - "plugin": app.Spec.Source.Plugin.Name, + "plugin": app.Spec.GetSource().Plugin.Name, }).Warnf(argocommon.ConfigMapPluginDeprecationWarning) } @@ -944,10 +947,10 @@ func (s *Server) Delete(ctx context.Context, q *application.ApplicationDeleteReq return nil, err } - if a.Spec.Source.Plugin != nil && a.Spec.Source.Plugin.Name != "" { + if a.Spec.GetSource().Plugin != nil && a.Spec.GetSource().Plugin.Name != "" { log.WithFields(map[string]interface{}{ "application": a.Name, - "plugin": a.Spec.Source.Plugin.Name, + "plugin": a.Spec.GetSource().Plugin.Name, }).Warnf(argocommon.ConfigMapPluginDeprecationWarning) } @@ -1113,16 +1116,6 @@ func (s *Server) validateAndNormalizeApp(ctx context.Context, app *appv1.Applica return err } } - - // If source is Kustomize add build options - kustomizeSettings, err := s.settingsMgr.GetKustomizeSettings() - if err != nil { - return fmt.Errorf("error getting kustomize settings: %w", err) - } - kustomizeOptions, err := kustomizeSettings.GetOptions(app.Spec.Source) - if err != nil { - return fmt.Errorf("error getting kustomize options from settings: %w", err) - } plugins, err := s.plugins() if err != nil { return fmt.Errorf("error getting plugins: %w", err) @@ -1134,10 +1127,12 @@ func (s *Server) validateAndNormalizeApp(ctx context.Context, app *appv1.Applica var conditions []appv1.ApplicationCondition if validate { - conditions, err = argo.ValidateRepo(ctx, app, s.repoClientset, s.db, kustomizeOptions, plugins, s.kubectl, proj, s.settingsMgr) + conditions := make([]appv1.ApplicationCondition, 0) + condition, err := argo.ValidateRepo(ctx, app, s.repoClientset, s.db, plugins, s.kubectl, proj, s.settingsMgr) if err != nil { return fmt.Errorf("error validating the repo: %w", err) } + conditions = append(conditions, condition...) if len(conditions) > 0 { return status.Errorf(codes.InvalidArgument, "application spec for %s is invalid: %s", app.Name, argo.FormatAppConditions(conditions)) } @@ -1357,10 +1352,11 @@ func (s *Server) ResourceTree(ctx context.Context, q *application.ResourcesQuery return nil, err } - if a.Spec.Source.Plugin != nil && a.Spec.Source.Plugin.Name != "" { + source := a.Spec.GetSource() + if source.Plugin != nil && source.Plugin.Name != "" { log.WithFields(map[string]interface{}{ "application": a.Name, - "plugin": a.Spec.Source.Plugin.Name, + "plugin": source.Plugin.Name, }).Warnf(argocommon.ConfigMapPluginDeprecationWarning) } @@ -1400,14 +1396,15 @@ func (s *Server) RevisionMetadata(ctx context.Context, q *application.RevisionMe return nil, err } - if a.Spec.Source.Plugin != nil && a.Spec.Source.Plugin.Name != "" { + source := a.Spec.GetSource() + if source.Plugin != nil && source.Plugin.Name != "" { log.WithFields(map[string]interface{}{ "application": a.Name, - "plugin": a.Spec.Source.Plugin.Name, + "plugin": source.Plugin.Name, }).Warnf(argocommon.ConfigMapPluginDeprecationWarning) } - repo, err := s.db.GetRepository(ctx, a.Spec.Source.RepoURL) + repo, err := s.db.GetRepository(ctx, source.RepoURL) if err != nil { return nil, fmt.Errorf("error getting repository by URL: %w", err) } @@ -1447,10 +1444,11 @@ func (s *Server) ManagedResources(ctx context.Context, q *application.ResourcesQ return nil, fmt.Errorf("error verifying rbac: %w", err) } - if a.Spec.Source.Plugin != nil && a.Spec.Source.Plugin.Name != "" { + source := a.Spec.GetSource() + if source.Plugin != nil && source.Plugin.Name != "" { log.WithFields(map[string]interface{}{ "application": a.Name, - "plugin": a.Spec.Source.Plugin.Name, + "plugin": source.Plugin.Name, }).Warnf(argocommon.ConfigMapPluginDeprecationWarning) } @@ -1517,10 +1515,11 @@ func (s *Server) PodLogs(q *application.ApplicationPodLogsQuery, ws application. return err } - if a.Spec.Source.Plugin != nil && a.Spec.Source.Plugin.Name != "" { + source := a.Spec.GetSource() + if source.Plugin != nil && source.Plugin.Name != "" { log.WithFields(map[string]interface{}{ "application": a.Name, - "plugin": a.Spec.Source.Plugin.Name, + "plugin": source.Plugin.Name, }).Warnf(argocommon.ConfigMapPluginDeprecationWarning) } @@ -1737,10 +1736,11 @@ func (s *Server) Sync(ctx context.Context, syncReq *application.ApplicationSyncR return nil, err } - if a.Spec.Source.Plugin != nil && a.Spec.Source.Plugin.Name != "" { + source := a.Spec.GetSource() + if source.Plugin != nil && source.Plugin.Name != "" { log.WithFields(map[string]interface{}{ "application": a.Name, - "plugin": a.Spec.Source.Plugin.Name, + "plugin": source.Plugin.Name, }).Warnf(argocommon.ConfigMapPluginDeprecationWarning) } @@ -1756,8 +1756,8 @@ func (s *Server) Sync(ctx context.Context, syncReq *application.ApplicationSyncR return nil, status.Errorf(codes.FailedPrecondition, "application is deleting") } if a.Spec.SyncPolicy != nil && a.Spec.SyncPolicy.Automated != nil { - if syncReq.GetRevision() != "" && syncReq.GetRevision() != text.FirstNonEmpty(a.Spec.Source.TargetRevision, "HEAD") { - return nil, status.Errorf(codes.FailedPrecondition, "Cannot sync to %s: auto-sync currently set to %s", syncReq.GetRevision(), a.Spec.Source.TargetRevision) + 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) @@ -1836,10 +1836,11 @@ func (s *Server) Rollback(ctx context.Context, rollbackReq *application.Applicat return nil, err } - if a.Spec.Source.Plugin != nil && a.Spec.Source.Plugin.Name != "" { + source := a.Spec.GetSource() + if source.Plugin != nil && source.Plugin.Name != "" { log.WithFields(map[string]interface{}{ "application": a.Name, - "plugin": a.Spec.Source.Plugin.Name, + "plugin": source.Plugin.Name, }).Warnf(argocommon.ConfigMapPluginDeprecationWarning) } @@ -1959,9 +1960,9 @@ func (s *Server) resolveRevision(ctx context.Context, app *appv1.Application, sy } ambiguousRevision := syncReq.GetRevision() if ambiguousRevision == "" { - ambiguousRevision = app.Spec.Source.TargetRevision + ambiguousRevision = app.Spec.GetSource().TargetRevision } - repo, err := s.db.GetRepository(ctx, app.Spec.Source.RepoURL) + repo, err := s.db.GetRepository(ctx, app.Spec.GetSource().RepoURL) if err != nil { return "", "", fmt.Errorf("error getting repository by URL: %w", err) } @@ -1971,7 +1972,8 @@ func (s *Server) resolveRevision(ctx context.Context, app *appv1.Application, sy } defer ioutil.Close(conn) - if !app.Spec.Source.IsHelm() { + source := app.Spec.GetSource() + if !source.IsHelm() { if git.IsCommitSHA(ambiguousRevision) { // If it's already a commit SHA, then no need to look it up return ambiguousRevision, ambiguousRevision, nil @@ -2266,10 +2268,11 @@ func (s *Server) GetApplicationSyncWindows(ctx context.Context, q *application.A return nil, err } - if a.Spec.Source.Plugin != nil && a.Spec.Source.Plugin.Name != "" { + source := a.Spec.GetSource() + if source.Plugin != nil && source.Plugin.Name != "" { log.WithFields(map[string]interface{}{ "application": a.Name, - "plugin": a.Spec.Source.Plugin.Name, + "plugin": source.Plugin.Name, }).Warnf(argocommon.ConfigMapPluginDeprecationWarning) } diff --git a/server/application/application_test.go b/server/application/application_test.go index 7eb6ae3357463..7569734d33b42 100644 --- a/server/application/application_test.go +++ b/server/application/application_test.go @@ -540,6 +540,9 @@ func TestDeleteApp(t *testing.T) { deleted = true return true, nil, nil }) + fakeAppCs.AddReactor("get", "applications", func(action kubetesting.Action) (handled bool, ret runtime.Object, err error) { + return true, &appsv1.Application{Spec: appsv1.ApplicationSpec{Source: &appsv1.ApplicationSource{}}}, nil + }) appServer.appclientset = fakeAppCs trueVar := true @@ -864,6 +867,9 @@ func TestGetCachedAppState(t *testing.T) { } appServer := newTestAppServer(testApp, testProj) fakeClientSet := appServer.appclientset.(*apps.Clientset) + fakeClientSet.AddReactor("get", "applications", func(action kubetesting.Action) (handled bool, ret runtime.Object, err error) { + return true, &appsv1.Application{Spec: appsv1.ApplicationSpec{Source: &appsv1.ApplicationSource{}}}, nil + }) t.Run("NoError", func(t *testing.T) { err := appServer.getCachedAppState(context.Background(), testApp, func() error { return nil @@ -887,6 +893,9 @@ func TestGetCachedAppState(t *testing.T) { appServer.appBroadcaster.OnUpdate(testApp, updated) return true, testApp, nil }) + fakeClientSet.AddReactor("get", "applications", func(action kubetesting.Action) (handled bool, ret runtime.Object, err error) { + return true, &appsv1.Application{Spec: appsv1.ApplicationSpec{Source: &appsv1.ApplicationSource{}}}, nil + }) fakeClientSet.Unlock() fakeClientSet.AddWatchReactor("applications", func(action kubetesting.Action) (handled bool, ret watch.Interface, err error) { return true, watcher, nil @@ -1086,7 +1095,7 @@ func TestGetAppRefresh_HardRefresh(t *testing.T) { assert.NoError(t, err) require.NotNil(t, getAppDetailsQuery) assert.True(t, getAppDetailsQuery.NoCache) - assert.Equal(t, &testApp.Spec.Source, getAppDetailsQuery.Source) + assert.Equal(t, testApp.Spec.Source, getAppDetailsQuery.Source) assert.NoError(t, err) select { diff --git a/server/extension/extension_test.go b/server/extension/extension_test.go index cc15369f5bceb..a6fa7b5d6cf8f 100644 --- a/server/extension/extension_test.go +++ b/server/extension/extension_test.go @@ -3,21 +3,22 @@ package extension_test import ( "context" "fmt" - "io/ioutil" + "io" "net/http" "net/http/httptest" "strings" "testing" - v1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v2/server/extension" - "github.com/argoproj/argo-cd/v2/server/extension/mocks" - "github.com/argoproj/argo-cd/v2/util/settings" "github.com/gorilla/mux" "github.com/sirupsen/logrus/hooks/test" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" + + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/server/extension" + "github.com/argoproj/argo-cd/v2/server/extension/mocks" + "github.com/argoproj/argo-cd/v2/util/settings" ) func TestRegisterHandlers(t *testing.T) { @@ -196,7 +197,7 @@ func TestExtensionsHandlers(t *testing.T) { require.NoError(t, err) require.NotNil(t, resp) require.Equal(t, http.StatusOK, resp.StatusCode) - body, err := ioutil.ReadAll(resp.Body) + body, err := io.ReadAll(resp.Body) require.NoError(t, err) actual := strings.TrimSuffix(string(body), "\n") assert.Equal(t, backendResponse, actual) @@ -259,14 +260,14 @@ func TestExtensionsHandlers(t *testing.T) { // then require.NotNil(t, resp1) require.Equal(t, http.StatusOK, resp1.StatusCode) - body, err := ioutil.ReadAll(resp1.Body) + body, err := io.ReadAll(resp1.Body) require.NoError(t, err) actual := strings.TrimSuffix(string(body), "\n") assert.Equal(t, response1, actual) require.NotNil(t, resp2) require.Equal(t, http.StatusOK, resp2.StatusCode) - body, err = ioutil.ReadAll(resp2.Body) + body, err = io.ReadAll(resp2.Body) require.NoError(t, err) actual = strings.TrimSuffix(string(body), "\n") assert.Equal(t, response2, actual) diff --git a/server/project/project.go b/server/project/project.go index 9c86cf1ead471..3bae8b28e9b4c 100644 --- a/server/project/project.go +++ b/server/project/project.go @@ -397,7 +397,7 @@ func (s *Server) Update(ctx context.Context, q *project.ProjectUpdateRequest) (* } for _, a := range argo.FilterByProjects(appsList.Items, []string{q.Project.Name}) { - if oldProj.IsSourcePermitted(a.Spec.Source) { + if oldProj.IsSourcePermitted(a.Spec.GetSource()) { srcValidatedApps = append(srcValidatedApps, a) } @@ -415,7 +415,7 @@ func (s *Server) Update(ctx context.Context, q *project.ProjectUpdateRequest) (* invalidDstCount := 0 for _, a := range srcValidatedApps { - if !q.Project.IsSourcePermitted(a.Spec.Source) { + if !q.Project.IsSourcePermitted(a.Spec.GetSource()) { invalidSrcCount++ } } diff --git a/server/project/project_test.go b/server/project/project_test.go index 00beec73c599b..caf0df9f3ebac 100644 --- a/server/project/project_test.go +++ b/server/project/project_test.go @@ -69,7 +69,7 @@ func TestProjectServer(t *testing.T) { } existingApp := v1alpha1.Application{ ObjectMeta: v1.ObjectMeta{Name: "test", Namespace: "default"}, - Spec: v1alpha1.ApplicationSpec{Project: "test", Destination: v1alpha1.ApplicationDestination{Namespace: "ns3", Server: "https://server3"}}, + Spec: v1alpha1.ApplicationSpec{Source: &v1alpha1.ApplicationSource{}, Project: "test", Destination: v1alpha1.ApplicationDestination{Namespace: "ns3", Server: "https://server3"}}, } policyTemplate := "p, proj:%s:%s, applications, %s, %s/%s, %s" @@ -166,7 +166,7 @@ func TestProjectServer(t *testing.T) { t.Run("TestRemoveDestinationSuccessful", func(t *testing.T) { existingApp := v1alpha1.Application{ ObjectMeta: v1.ObjectMeta{Name: "test", Namespace: "default"}, - Spec: v1alpha1.ApplicationSpec{Project: "test", Destination: v1alpha1.ApplicationDestination{Namespace: "ns3", Server: "https://server3"}}, + Spec: v1alpha1.ApplicationSpec{Source: &v1alpha1.ApplicationSource{}, Project: "test", Destination: v1alpha1.ApplicationDestination{Namespace: "ns3", Server: "https://server3"}}, } argoDB := db.NewDB("default", settingsMgr, kubeclientset) @@ -183,7 +183,7 @@ func TestProjectServer(t *testing.T) { t.Run("TestRemoveDestinationUsedByApp", func(t *testing.T) { existingApp := v1alpha1.Application{ ObjectMeta: v1.ObjectMeta{Name: "test", Namespace: "default"}, - Spec: v1alpha1.ApplicationSpec{Project: "test", Destination: v1alpha1.ApplicationDestination{Namespace: "ns1", Server: "https://server1"}}, + Spec: v1alpha1.ApplicationSpec{Source: &v1alpha1.ApplicationSource{}, Project: "test", Destination: v1alpha1.ApplicationDestination{Namespace: "ns1", Server: "https://server1"}}, } argoDB := db.NewDB("default", settingsMgr, kubeclientset) @@ -202,7 +202,7 @@ func TestProjectServer(t *testing.T) { t.Run("TestRemoveSourceSuccessful", func(t *testing.T) { existingApp := v1alpha1.Application{ ObjectMeta: v1.ObjectMeta{Name: "test", Namespace: "default"}, - Spec: v1alpha1.ApplicationSpec{Project: "test"}, + Spec: v1alpha1.ApplicationSpec{Source: &v1alpha1.ApplicationSource{}, Project: "test"}, } argoDB := db.NewDB("default", settingsMgr, kubeclientset) @@ -219,7 +219,7 @@ func TestProjectServer(t *testing.T) { t.Run("TestRemoveSourceUsedByApp", func(t *testing.T) { existingApp := v1alpha1.Application{ ObjectMeta: v1.ObjectMeta{Name: "test", Namespace: "default"}, - Spec: v1alpha1.ApplicationSpec{Project: "test", Source: v1alpha1.ApplicationSource{RepoURL: "https://github.com/argoproj/argo-cd.git"}}, + Spec: v1alpha1.ApplicationSpec{Project: "test", Source: &v1alpha1.ApplicationSource{RepoURL: "https://github.com/argoproj/argo-cd.git"}}, } argoDB := db.NewDB("default", settingsMgr, kubeclientset) @@ -240,7 +240,7 @@ func TestProjectServer(t *testing.T) { proj.Spec.SourceRepos = []string{"https://github.com/argoproj/argo-cd.git", "https://github.com/argoproj/*"} existingApp := v1alpha1.Application{ ObjectMeta: v1.ObjectMeta{Name: "test", Namespace: "default"}, - Spec: v1alpha1.ApplicationSpec{Project: "test", Source: v1alpha1.ApplicationSource{RepoURL: "https://github.com/argoproj/argo-cd.git"}}, + Spec: v1alpha1.ApplicationSpec{Project: "test", Source: &v1alpha1.ApplicationSource{RepoURL: "https://github.com/argoproj/argo-cd.git"}}, } argoDB := db.NewDB("default", settingsMgr, kubeclientset) projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(proj, &existingApp), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB) @@ -262,7 +262,7 @@ func TestProjectServer(t *testing.T) { } existingApp := v1alpha1.Application{ ObjectMeta: v1.ObjectMeta{Name: "test", Namespace: "default"}, - Spec: v1alpha1.ApplicationSpec{Project: "test", Destination: v1alpha1.ApplicationDestination{ + Spec: v1alpha1.ApplicationSpec{Source: &v1alpha1.ApplicationSource{}, Project: "test", Destination: v1alpha1.ApplicationDestination{ Server: "https://server1", Namespace: "org1-team1", }}, diff --git a/server/repository/repository.go b/server/repository/repository.go index 23667d6cecb6f..0cf976828e8d2 100644 --- a/server/repository/repository.go +++ b/server/repository/repository.go @@ -5,6 +5,7 @@ import ( "reflect" "context" + "github.com/argoproj/gitops-engine/pkg/utils/kube" "github.com/argoproj/gitops-engine/pkg/utils/text" log "github.com/sirupsen/logrus" @@ -553,7 +554,7 @@ func (s *Server) isRepoPermittedInProject(repo string, projName string) error { // isSourceInHistory checks if the supplied application source is either our current application // source, or was something which we synced to previously. func isSourceInHistory(app *v1alpha1.Application, source v1alpha1.ApplicationSource) bool { - if source.Equals(app.Spec.Source) { + if source.Equals(app.Spec.GetSource()) { return true } // Iterate history. When comparing items in our history, use the actual synced revision to diff --git a/server/repository/repository_test.go b/server/repository/repository_test.go index a76d373976f7b..0b5b20be025ee 100644 --- a/server/repository/repository_test.go +++ b/server/repository/repository_test.go @@ -98,7 +98,7 @@ var ( }, Spec: appsv1.ApplicationSpec{ Project: "default", - Source: appsv1.ApplicationSource{ + Source: &appsv1.ApplicationSource{ RepoURL: "https://test", TargetRevision: "HEAD", Helm: &appsv1.ApplicationSourceHelm{ @@ -497,7 +497,7 @@ func TestRepositoryServerGetAppDetails(t *testing.T) { s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projLister, settingsMgr) resp, err := s.GetAppDetails(context.TODO(), &repository.RepoAppDetailsQuery{ - Source: &guestbookApp.Spec.Source, + Source: guestbookApp.Spec.GetSourcePtr(), AppName: "guestbook", AppProject: "default", }) @@ -516,7 +516,7 @@ func TestRepositoryServerGetAppDetails(t *testing.T) { s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projLister, settingsMgr) resp, err := s.GetAppDetails(context.TODO(), &repository.RepoAppDetailsQuery{ - Source: &guestbookApp.Spec.Source, + Source: guestbookApp.Spec.GetSourcePtr(), AppName: "guestbook", AppProject: "mismatch", }) diff --git a/test/e2e/app_autosync_test.go b/test/e2e/app_autosync_test.go index e9da1f659937e..6e3c1443285e5 100644 --- a/test/e2e/app_autosync_test.go +++ b/test/e2e/app_autosync_test.go @@ -4,10 +4,9 @@ import ( "context" "testing" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - . "github.com/argoproj/gitops-engine/pkg/sync/common" "github.com/stretchr/testify/assert" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" . "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" diff --git a/test/e2e/app_management_ns_test.go b/test/e2e/app_management_ns_test.go index 4d2bc2dfaa3e0..68000825b09f1 100644 --- a/test/e2e/app_management_ns_test.go +++ b/test/e2e/app_management_ns_test.go @@ -35,6 +35,7 @@ import ( projectFixture "github.com/argoproj/argo-cd/v2/test/e2e/fixture/project" repoFixture "github.com/argoproj/argo-cd/v2/test/e2e/fixture/repos" "github.com/argoproj/argo-cd/v2/test/e2e/testdata" + . "github.com/argoproj/argo-cd/v2/util/argo" . "github.com/argoproj/argo-cd/v2/util/errors" "github.com/argoproj/argo-cd/v2/util/io" @@ -284,8 +285,8 @@ func TestNamespacedAppCreation(t *testing.T) { And(func(app *Application) { assert.Equal(t, Name(), app.Name) assert.Equal(t, AppNamespace(), app.Namespace) - assert.Equal(t, RepoURL(RepoURLTypeFile), app.Spec.Source.RepoURL) - assert.Equal(t, guestbookPath, app.Spec.Source.Path) + assert.Equal(t, RepoURL(RepoURLTypeFile), app.Spec.GetSource().RepoURL) + assert.Equal(t, guestbookPath, app.Spec.GetSource().Path) assert.Equal(t, DeploymentNamespace(), app.Spec.Destination.Namespace) assert.Equal(t, KubernetesInternalAPIServerAddr, app.Spec.Destination.Server) }). @@ -313,7 +314,7 @@ func TestNamespacedAppCreation(t *testing.T) { And(func(app *Application) { assert.Equal(t, "label", app.Labels["test"]) assert.Equal(t, "annotation", app.Annotations["test"]) - assert.Equal(t, "master", app.Spec.Source.TargetRevision) + assert.Equal(t, "master", app.Spec.GetSource().TargetRevision) }) } @@ -332,8 +333,8 @@ func TestNamespacedAppCreationWithoutForceUpdate(t *testing.T) { And(func(app *Application) { assert.Equal(t, ctx.AppName(), app.Name) assert.Equal(t, AppNamespace(), app.Namespace) - assert.Equal(t, RepoURL(RepoURLTypeFile), app.Spec.Source.RepoURL) - assert.Equal(t, guestbookPath, app.Spec.Source.Path) + assert.Equal(t, RepoURL(RepoURLTypeFile), app.Spec.GetSource().RepoURL) + assert.Equal(t, guestbookPath, app.Spec.GetSource().Path) assert.Equal(t, DeploymentNamespace(), app.Spec.Destination.Namespace) assert.Equal(t, "in-cluster", app.Spec.Destination.Name) }). @@ -521,12 +522,12 @@ func TestNamespacedAppRollbackSuccessful(t *testing.T) { ID: 1, Revision: app.Status.Sync.Revision, DeployedAt: metav1.Time{Time: metav1.Now().UTC().Add(-1 * time.Minute)}, - Source: app.Spec.Source, + Source: app.Spec.GetSource(), }, { ID: 2, Revision: "cdb", DeployedAt: metav1.Time{Time: metav1.Now().UTC().Add(-2 * time.Minute)}, - Source: app.Spec.Source, + Source: app.Spec.GetSource(), }} patch, _, err := diff.CreateTwoWayMergePatch(app, appWithHistory, &Application{}) require.NoError(t, err) @@ -2190,8 +2191,8 @@ spec: assert.Equal(t, map[string]string{"labels.local/from-file": "file", "labels.local/from-args": "args"}, app.ObjectMeta.Labels) assert.Equal(t, map[string]string{"annotations.local/from-file": "file"}, app.ObjectMeta.Annotations) assert.Equal(t, []string{"resources-finalizer.argocd.argoproj.io"}, app.ObjectMeta.Finalizers) - assert.Equal(t, path, app.Spec.Source.Path) - assert.Equal(t, []HelmParameter{{Name: "foo", Value: "foo"}}, app.Spec.Source.Helm.Parameters) + assert.Equal(t, path, app.Spec.GetSource().Path) + assert.Equal(t, []HelmParameter{{Name: "foo", Value: "foo"}}, app.Spec.GetSource().Helm.Parameters) }) } diff --git a/test/e2e/app_management_test.go b/test/e2e/app_management_test.go index 013bf1552ae78..03cd0c109c2ae 100644 --- a/test/e2e/app_management_test.go +++ b/test/e2e/app_management_test.go @@ -277,8 +277,8 @@ func TestAppCreation(t *testing.T) { Expect(SyncStatusIs(SyncStatusCodeOutOfSync)). And(func(app *Application) { assert.Equal(t, Name(), app.Name) - assert.Equal(t, RepoURL(RepoURLTypeFile), app.Spec.Source.RepoURL) - assert.Equal(t, guestbookPath, app.Spec.Source.Path) + assert.Equal(t, RepoURL(RepoURLTypeFile), app.Spec.GetSource().RepoURL) + assert.Equal(t, guestbookPath, app.Spec.GetSource().Path) assert.Equal(t, DeploymentNamespace(), app.Spec.Destination.Namespace) assert.Equal(t, KubernetesInternalAPIServerAddr, app.Spec.Destination.Server) }). @@ -306,7 +306,7 @@ func TestAppCreation(t *testing.T) { And(func(app *Application) { assert.Equal(t, "label", app.Labels["test"]) assert.Equal(t, "annotation", app.Annotations["test"]) - assert.Equal(t, "master", app.Spec.Source.TargetRevision) + assert.Equal(t, "master", app.Spec.GetSource().TargetRevision) }) } @@ -322,8 +322,8 @@ func TestAppCreationWithoutForceUpdate(t *testing.T) { Expect(SyncStatusIs(SyncStatusCodeOutOfSync)). And(func(app *Application) { assert.Equal(t, ctx.AppName(), app.Name) - assert.Equal(t, RepoURL(RepoURLTypeFile), app.Spec.Source.RepoURL) - assert.Equal(t, guestbookPath, app.Spec.Source.Path) + assert.Equal(t, RepoURL(RepoURLTypeFile), app.Spec.GetSource().RepoURL) + assert.Equal(t, guestbookPath, app.Spec.GetSource().Path) assert.Equal(t, DeploymentNamespace(), app.Spec.Destination.Namespace) assert.Equal(t, "in-cluster", app.Spec.Destination.Name) }). @@ -494,12 +494,12 @@ func TestAppRollbackSuccessful(t *testing.T) { ID: 1, Revision: app.Status.Sync.Revision, DeployedAt: metav1.Time{Time: metav1.Now().UTC().Add(-1 * time.Minute)}, - Source: app.Spec.Source, + Source: app.Spec.GetSource(), }, { ID: 2, Revision: "cdb", DeployedAt: metav1.Time{Time: metav1.Now().UTC().Add(-2 * time.Minute)}, - Source: app.Spec.Source, + Source: app.Spec.GetSource(), }} patch, _, err := diff.CreateTwoWayMergePatch(app, appWithHistory, &Application{}) require.NoError(t, err) @@ -1896,8 +1896,8 @@ spec: assert.Equal(t, map[string]string{"labels.local/from-file": "file", "labels.local/from-args": "args"}, app.ObjectMeta.Labels) assert.Equal(t, map[string]string{"annotations.local/from-file": "file"}, app.ObjectMeta.Annotations) assert.Equal(t, []string{"resources-finalizer.argocd.argoproj.io"}, app.ObjectMeta.Finalizers) - assert.Equal(t, path, app.Spec.Source.Path) - assert.Equal(t, []HelmParameter{{Name: "foo", Value: "foo"}}, app.Spec.Source.Helm.Parameters) + assert.Equal(t, path, app.Spec.GetSource().Path) + assert.Equal(t, []HelmParameter{{Name: "foo", Value: "foo"}}, app.Spec.GetSource().Helm.Parameters) }) } diff --git a/test/e2e/app_multiple_sources_test.go b/test/e2e/app_multiple_sources_test.go new file mode 100644 index 0000000000000..f7bf00c143d9b --- /dev/null +++ b/test/e2e/app_multiple_sources_test.go @@ -0,0 +1,165 @@ +package e2e + +import ( + "testing" + + . "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + . "github.com/argoproj/argo-cd/v2/test/e2e/fixture" + . "github.com/argoproj/argo-cd/v2/test/e2e/fixture/app" + . "github.com/argoproj/argo-cd/v2/util/argo" + "github.com/stretchr/testify/assert" +) + +func TestMultiSourceAppCreation(t *testing.T) { + sources := []ApplicationSource{{ + RepoURL: RepoURL(RepoURLTypeFile), + Path: guestbookPath, + }, { + RepoURL: RepoURL(RepoURLTypeFile), + Path: "two-nice-pods", + }} + ctx := Given(t) + ctx. + Sources(sources). + When(). + CreateMultiSourceAppFromFile(). + Then(). + Expect(SyncStatusIs(SyncStatusCodeOutOfSync)). + And(func(app *Application) { + assert.Equal(t, Name(), app.Name) + for i, source := range app.Spec.GetSources() { + assert.Equal(t, sources[i].RepoURL, source.RepoURL) + assert.Equal(t, sources[i].Path, source.Path) + } + assert.Equal(t, DeploymentNamespace(), app.Spec.Destination.Namespace) + assert.Equal(t, KubernetesInternalAPIServerAddr, app.Spec.Destination.Server) + }). + Expect(Event(EventReasonResourceCreated, "create")). + And(func(_ *Application) { + // app should be listed + output, err := RunCli("app", "list") + assert.NoError(t, err) + assert.Contains(t, output, Name()) + }). + Expect(Success("")). + When().Refresh(RefreshTypeNormal).Then(). + Expect(Success("")). + And(func(app *Application) { + statusByName := map[string]SyncStatusCode{} + for _, r := range app.Status.Resources { + statusByName[r.Name] = r.Status + } + // check if the app has 3 resources, guestbook and 2 pods + assert.Len(t, statusByName, 3) + assert.Equal(t, SyncStatusCodeSynced, statusByName["pod-1"]) + assert.Equal(t, SyncStatusCodeSynced, statusByName["pod-2"]) + assert.Equal(t, SyncStatusCodeSynced, statusByName["guestbook-ui"]) + }) +} + +func TestMultiSourceAppWithHelmExternalValueFiles(t *testing.T) { + sources := []ApplicationSource{{ + RepoURL: RepoURL(RepoURLTypeFile), + Ref: "values", + }, { + RepoURL: "https://github.com/argoproj/argocd-example-apps.git", + TargetRevision: "HEAD", + Path: "helm-guestbook", + Helm: &ApplicationSourceHelm{ + ReleaseName: "helm-guestbook", + ValueFiles: []string{ + "$values/multiple-source-values/values.yaml", + }, + }, + }} + ctx := Given(t) + ctx. + Sources(sources). + When(). + CreateMultiSourceAppFromFile(). + Then(). + Expect(SyncStatusIs(SyncStatusCodeOutOfSync)). + And(func(app *Application) { + assert.Equal(t, Name(), app.Name) + for i, source := range app.Spec.GetSources() { + assert.Equal(t, sources[i].RepoURL, source.RepoURL) + assert.Equal(t, sources[i].Path, source.Path) + } + assert.Equal(t, DeploymentNamespace(), app.Spec.Destination.Namespace) + assert.Equal(t, KubernetesInternalAPIServerAddr, app.Spec.Destination.Server) + }). + Expect(Event(EventReasonResourceCreated, "create")). + And(func(_ *Application) { + // app should be listed + output, err := RunCli("app", "list") + assert.NoError(t, err) + assert.Contains(t, output, Name()) + }). + Expect(Success("")). + When().Refresh(RefreshTypeNormal).Then(). + Expect(Success("")). + And(func(app *Application) { + statusByName := map[string]SyncStatusCode{} + for _, r := range app.Status.Resources { + statusByName[r.Name] = r.Status + } + // check if the app has 3 resources, guestbook and 2 pods + assert.Len(t, statusByName, 1) + assert.Equal(t, SyncStatusCodeSynced, statusByName["helm-guestbook"]) + }) +} + +func TestMultiSourceAppWithSourceOverride(t *testing.T) { + sources := []ApplicationSource{{ + RepoURL: RepoURL(RepoURLTypeFile), + Path: guestbookPath, + }, { + RepoURL: RepoURL(RepoURLTypeFile), + Path: "two-nice-pods", + }, { + RepoURL: RepoURL(RepoURLTypeFile), + Path: "multiple-source-values", + }} + ctx := Given(t) + ctx. + Sources(sources). + When(). + CreateMultiSourceAppFromFile(). + Then(). + Expect(SyncStatusIs(SyncStatusCodeOutOfSync)). + And(func(app *Application) { + assert.Equal(t, Name(), app.Name) + for i, source := range app.Spec.GetSources() { + assert.Equal(t, sources[i].RepoURL, source.RepoURL) + assert.Equal(t, sources[i].Path, source.Path) + } + assert.Equal(t, DeploymentNamespace(), app.Spec.Destination.Namespace) + assert.Equal(t, KubernetesInternalAPIServerAddr, app.Spec.Destination.Server) + }). + Expect(Event(EventReasonResourceCreated, "create")). + And(func(_ *Application) { + // app should be listed + output, err := RunCli("app", "list") + assert.NoError(t, err) + assert.Contains(t, output, Name()) + }). + Expect(Success("")). + When().Refresh(RefreshTypeNormal).Then(). + Expect(Success("")). + And(func(app *Application) { + statusByName := map[string]SyncStatusCode{} + for _, r := range app.Status.Resources { + statusByName[r.Name] = r.Status + } + // check if the app has 3 resources, guestbook and 2 pods + assert.Len(t, statusByName, 3) + assert.Equal(t, SyncStatusCodeSynced, statusByName["pod-1"]) + assert.Equal(t, SyncStatusCodeSynced, statusByName["pod-2"]) + assert.Equal(t, SyncStatusCodeSynced, statusByName["guestbook-ui"]) + + // check if label was added to the pod to make sure resource was taken from the later source + output, err := Run("", "kubectl", "describe", "pods", "pod-1", "-n", DeploymentNamespace()) + assert.NoError(t, err) + assert.Contains(t, output, "foo=bar") + }) +} diff --git a/test/e2e/app_namespaces_test.go b/test/e2e/app_namespaces_test.go index 8ee41aa0d7f2b..d66cbaa1494ef 100644 --- a/test/e2e/app_namespaces_test.go +++ b/test/e2e/app_namespaces_test.go @@ -28,8 +28,8 @@ func TestAppCreationInOtherNamespace(t *testing.T) { And(func(app *Application) { assert.Equal(t, ctx.AppName(), app.Name) assert.Equal(t, AppNamespace(), app.Namespace) - assert.Equal(t, RepoURL(RepoURLTypeFile), app.Spec.Source.RepoURL) - assert.Equal(t, guestbookPath, app.Spec.Source.Path) + assert.Equal(t, RepoURL(RepoURLTypeFile), app.Spec.GetSource().RepoURL) + assert.Equal(t, guestbookPath, app.Spec.GetSource().Path) assert.Equal(t, DeploymentNamespace(), app.Spec.Destination.Namespace) assert.Equal(t, KubernetesInternalAPIServerAddr, app.Spec.Destination.Server) }). @@ -57,7 +57,7 @@ func TestAppCreationInOtherNamespace(t *testing.T) { And(func(app *Application) { assert.Equal(t, "label", app.Labels["test"]) assert.Equal(t, "annotation", app.Annotations["test"]) - assert.Equal(t, "master", app.Spec.Source.TargetRevision) + assert.Equal(t, "master", app.Spec.GetSource().TargetRevision) }) } diff --git a/test/e2e/applicationset_test.go b/test/e2e/applicationset_test.go index a5afead1bb24f..913eb73079de1 100644 --- a/test/e2e/applicationset_test.go +++ b/test/e2e/applicationset_test.go @@ -57,7 +57,7 @@ func TestSimpleListGenerator(t *testing.T) { }, Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: argov1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: "guestbook", @@ -81,7 +81,7 @@ func TestSimpleListGenerator(t *testing.T) { ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{cluster}}-guestbook"}, Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: argov1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: "guestbook", @@ -149,7 +149,7 @@ func TestSimpleListGeneratorGoTemplate(t *testing.T) { }, Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: argov1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: "guestbook", @@ -174,7 +174,7 @@ func TestSimpleListGeneratorGoTemplate(t *testing.T) { ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{.cluster}}-guestbook"}, Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: argov1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: "guestbook", @@ -242,7 +242,7 @@ func TestSimpleGitDirectoryGenerator(t *testing.T) { }, Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: argov1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: name, @@ -275,7 +275,7 @@ func TestSimpleGitDirectoryGenerator(t *testing.T) { ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{path.basename}}"}, Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: argov1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: "{{path}}", @@ -351,7 +351,7 @@ func TestSimpleGitDirectoryGeneratorGoTemplate(t *testing.T) { }, Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: argov1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: name, @@ -385,7 +385,7 @@ func TestSimpleGitDirectoryGeneratorGoTemplate(t *testing.T) { ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{.path.basename}}"}, Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: argov1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: "{{.path.path}}", @@ -462,7 +462,7 @@ func TestSimpleGitFilesGenerator(t *testing.T) { }, Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: argov1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: "guestbook", @@ -494,7 +494,7 @@ func TestSimpleGitFilesGenerator(t *testing.T) { ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{cluster.name}}-guestbook"}, Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: argov1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: "guestbook", @@ -571,7 +571,7 @@ func TestSimpleGitFilesGeneratorGoTemplate(t *testing.T) { }, Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: argov1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: "guestbook", @@ -604,7 +604,7 @@ func TestSimpleGitFilesGeneratorGoTemplate(t *testing.T) { ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{.cluster.name}}-guestbook"}, Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: argov1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: "guestbook", @@ -680,7 +680,7 @@ func TestSimpleGitFilesPreserveResourcesOnDeletion(t *testing.T) { ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{cluster.name}}-guestbook"}, Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: argov1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: "guestbook", @@ -741,7 +741,7 @@ func TestSimpleGitFilesPreserveResourcesOnDeletionGoTemplate(t *testing.T) { ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{.cluster.name}}-guestbook"}, Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: argov1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: "guestbook", @@ -994,7 +994,7 @@ func TestSimpleSCMProviderGenerator(t *testing.T) { }, Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: argov1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "git@github.com:argoproj/argo-cd.git", TargetRevision: "master", Path: "guestbook", @@ -1019,7 +1019,7 @@ func TestSimpleSCMProviderGenerator(t *testing.T) { ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{ repository }}-guestbook"}, Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: argov1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "{{ url }}", TargetRevision: "{{ branch }}", Path: "guestbook", @@ -1067,7 +1067,7 @@ func TestSimpleSCMProviderGeneratorGoTemplate(t *testing.T) { }, Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: argov1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "git@github.com:argoproj/argo-cd.git", TargetRevision: "master", Path: "guestbook", @@ -1093,7 +1093,7 @@ func TestSimpleSCMProviderGeneratorGoTemplate(t *testing.T) { ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{ .repository }}-guestbook"}, Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: argov1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "{{ .url }}", TargetRevision: "{{ .branch }}", Path: "guestbook", @@ -1136,7 +1136,7 @@ func TestCustomApplicationFinalizers(t *testing.T) { }, Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: argov1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: "guestbook", @@ -1161,7 +1161,7 @@ func TestCustomApplicationFinalizers(t *testing.T) { }, Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: argov1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: "guestbook", @@ -1202,7 +1202,7 @@ func TestCustomApplicationFinalizersGoTemplate(t *testing.T) { }, Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: argov1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: "guestbook", @@ -1228,7 +1228,7 @@ func TestCustomApplicationFinalizersGoTemplate(t *testing.T) { }, Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: argov1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: "guestbook", @@ -1302,7 +1302,7 @@ func TestSimplePullRequestGenerator(t *testing.T) { }, Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: argov1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "git@github.com:applicationset-test-org/argocd-example-apps.git", TargetRevision: "824a5c987fdfb2b0629e9dbf5f31636c69ba4772", Path: "kustomize-guestbook", @@ -1327,7 +1327,7 @@ func TestSimplePullRequestGenerator(t *testing.T) { ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "guestbook-{{ number }}"}, Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: argov1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "git@github.com:applicationset-test-org/argocd-example-apps.git", TargetRevision: "{{ head_sha }}", Path: "kustomize-guestbook", @@ -1378,7 +1378,7 @@ func TestSimplePullRequestGeneratorGoTemplate(t *testing.T) { }, Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: argov1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "git@github.com:applicationset-test-org/argocd-example-apps.git", TargetRevision: "824a5c987fdfb2b0629e9dbf5f31636c69ba4772", Path: "kustomize-guestbook", @@ -1406,7 +1406,7 @@ func TestSimplePullRequestGeneratorGoTemplate(t *testing.T) { Labels: map[string]string{"app": "{{index .labels 0}}"}}, Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: argov1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "git@github.com:applicationset-test-org/argocd-example-apps.git", TargetRevision: "{{ .head_sha }}", Path: "kustomize-guestbook", @@ -1453,7 +1453,7 @@ func TestGitGeneratorPrivateRepo(t *testing.T) { }, Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: argov1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: fixture.RepoURL(fixture.RepoURLTypeHTTPS), TargetRevision: "HEAD", Path: name, @@ -1483,7 +1483,7 @@ func TestGitGeneratorPrivateRepo(t *testing.T) { ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{path.basename}}"}, Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: argov1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: fixture.RepoURL(fixture.RepoURLTypeHTTPS), TargetRevision: "HEAD", Path: "{{path}}", @@ -1528,7 +1528,7 @@ func TestGitGeneratorPrivateRepoGoTemplate(t *testing.T) { }, Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: argov1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: fixture.RepoURL(fixture.RepoURLTypeHTTPS), TargetRevision: "HEAD", Path: name, @@ -1559,7 +1559,7 @@ func TestGitGeneratorPrivateRepoGoTemplate(t *testing.T) { ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{.path.basename}}"}, Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: argov1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: fixture.RepoURL(fixture.RepoURLTypeHTTPS), TargetRevision: "HEAD", Path: "{{.path.path}}", diff --git a/test/e2e/cluster_generator_test.go b/test/e2e/cluster_generator_test.go index dd3b98000bb31..c09fc9ed2fa34 100644 --- a/test/e2e/cluster_generator_test.go +++ b/test/e2e/cluster_generator_test.go @@ -26,7 +26,7 @@ func TestSimpleClusterGenerator(t *testing.T) { }, Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: argov1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: "guestbook", @@ -53,7 +53,7 @@ func TestSimpleClusterGenerator(t *testing.T) { ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{name}}-guestbook"}, Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: argov1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: "guestbook", @@ -119,7 +119,7 @@ func TestClusterGeneratorWithLocalCluster(t *testing.T) { }, Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: argov1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: "guestbook", @@ -177,7 +177,7 @@ func TestClusterGeneratorWithLocalCluster(t *testing.T) { ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{name}}-guestbook"}, Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: argov1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: "guestbook", @@ -236,7 +236,7 @@ func TestSimpleClusterGeneratorAddingCluster(t *testing.T) { }, Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: argov1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: "guestbook", @@ -268,7 +268,7 @@ func TestSimpleClusterGeneratorAddingCluster(t *testing.T) { ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{name}}-guestbook"}, Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: argov1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: "guestbook", @@ -318,7 +318,7 @@ func TestSimpleClusterGeneratorDeletingCluster(t *testing.T) { }, Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: argov1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: "guestbook", @@ -351,7 +351,7 @@ func TestSimpleClusterGeneratorDeletingCluster(t *testing.T) { ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{name}}-guestbook"}, Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: argov1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: "guestbook", diff --git a/test/e2e/clusterdecisiongenerator_e2e_test.go b/test/e2e/clusterdecisiongenerator_e2e_test.go index 5a352f191e1d4..44993dd409fde 100644 --- a/test/e2e/clusterdecisiongenerator_e2e_test.go +++ b/test/e2e/clusterdecisiongenerator_e2e_test.go @@ -27,7 +27,7 @@ func TestSimpleClusterDecisionResourceGenerator(t *testing.T) { }, Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: argov1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: "guestbook", @@ -65,7 +65,7 @@ func TestSimpleClusterDecisionResourceGenerator(t *testing.T) { ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{name}}-guestbook"}, Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: argov1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: "guestbook", @@ -129,7 +129,7 @@ func TestSimpleClusterDecisionResourceGeneratorAddingCluster(t *testing.T) { }, Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: argov1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: "guestbook", @@ -176,7 +176,7 @@ func TestSimpleClusterDecisionResourceGeneratorAddingCluster(t *testing.T) { ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{name}}-guestbook"}, Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: argov1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: "guestbook", @@ -224,7 +224,7 @@ func TestSimpleClusterDecisionResourceGeneratorDeletingClusterSecret(t *testing. }, Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: argov1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: "guestbook", @@ -272,7 +272,7 @@ func TestSimpleClusterDecisionResourceGeneratorDeletingClusterSecret(t *testing. ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{name}}-guestbook"}, Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: argov1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: "guestbook", @@ -321,7 +321,7 @@ func TestSimpleClusterDecisionResourceGeneratorDeletingClusterFromResource(t *te }, Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: argov1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: "guestbook", @@ -376,7 +376,7 @@ func TestSimpleClusterDecisionResourceGeneratorDeletingClusterFromResource(t *te ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{name}}-guestbook"}, Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: argov1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: "guestbook", diff --git a/test/e2e/custom_tool_test.go b/test/e2e/custom_tool_test.go index a5fffcd50ed58..cd587f42693b6 100644 --- a/test/e2e/custom_tool_test.go +++ b/test/e2e/custom_tool_test.go @@ -113,7 +113,7 @@ func TestCustomToolWithEnv(t *testing.T) { Path("guestbook"). When(). CreateFromFile(func(app *Application) { - app.Spec.Source.Plugin.Env = Env{{ + app.Spec.GetSource().Plugin.Env = Env{{ Name: "FOO", Value: "bar", }} diff --git a/test/e2e/fixture/app/actions.go b/test/e2e/fixture/app/actions.go index 928ca39b651fd..db606fb29c391 100644 --- a/test/e2e/fixture/app/actions.go +++ b/test/e2e/fixture/app/actions.go @@ -95,7 +95,7 @@ func (a *Actions) CreateFromFile(handler func(app *Application), flags ...string }, Spec: ApplicationSpec{ Project: a.context.project, - Source: ApplicationSource{ + Source: &ApplicationSource{ RepoURL: fixture.RepoURL(a.context.repoURLType), Path: a.context.path, }, @@ -105,14 +105,15 @@ func (a *Actions) CreateFromFile(handler func(app *Application), flags ...string }, }, } + source := app.Spec.GetSource() if a.context.namePrefix != "" || a.context.nameSuffix != "" { - app.Spec.Source.Kustomize = &ApplicationSourceKustomize{ + source.Kustomize = &ApplicationSourceKustomize{ NamePrefix: a.context.namePrefix, NameSuffix: a.context.nameSuffix, } } if a.context.configManagementPlugin != "" { - app.Spec.Source.Plugin = &ApplicationSourcePlugin{ + source.Plugin = &ApplicationSourcePlugin{ Name: a.context.configManagementPlugin, } } @@ -122,8 +123,9 @@ func (a *Actions) CreateFromFile(handler func(app *Application), flags ...string } if a.context.directoryRecurse { - app.Spec.Source.Directory = &ApplicationSourceDirectory{Recurse: true} + source.Directory = &ApplicationSourceDirectory{Recurse: true} } + app.Spec.Source = &source handler(app) data := grpc.MustMarshal(app) @@ -141,6 +143,43 @@ func (a *Actions) CreateFromFile(handler func(app *Application), flags ...string return a } +func (a *Actions) CreateMultiSourceAppFromFile(flags ...string) *Actions { + a.context.t.Helper() + app := &Application{ + ObjectMeta: v1.ObjectMeta{ + Name: a.context.AppName(), + Namespace: a.context.AppNamespace(), + }, + Spec: ApplicationSpec{ + Project: a.context.project, + Sources: a.context.sources, + Destination: ApplicationDestination{ + Server: a.context.destServer, + Namespace: fixture.DeploymentNamespace(), + }, + SyncPolicy: &SyncPolicy{ + Automated: &SyncPolicyAutomated{ + SelfHeal: true, + }, + }, + }, + } + + data := grpc.MustMarshal(app) + tmpFile, err := os.CreateTemp("", "") + errors.CheckError(err) + _, err = tmpFile.Write(data) + errors.CheckError(err) + + args := append([]string{ + "app", "create", + "-f", tmpFile.Name(), + }, flags...) + defer tmpFile.Close() + a.runCli(args...) + return a +} + func (a *Actions) CreateWithNoNameSpace(args ...string) *Actions { args = a.prepareCreateAppArgs(args) // are you adding new context values? if you only use them for this func, then use args instead diff --git a/test/e2e/fixture/app/context.go b/test/e2e/fixture/app/context.go index 923884cb69fa6..0aa94a33ac906 100644 --- a/test/e2e/fixture/app/context.go +++ b/test/e2e/fixture/app/context.go @@ -43,6 +43,7 @@ type Context struct { helmPassCredentials bool helmSkipCrds bool trackingMethod v1alpha1.TrackingMethod + sources []v1alpha1.ApplicationSource } type ContextArgs struct { @@ -365,3 +366,8 @@ func (c *Context) SetTrackingMethod(trackingMethod string) *Context { func (c *Context) GetTrackingMethod() v1alpha1.TrackingMethod { return c.trackingMethod } + +func (c *Context) Sources(sources []v1alpha1.ApplicationSource) *Context { + c.sources = sources + return c +} diff --git a/test/e2e/fixture/applicationsets/expectation.go b/test/e2e/fixture/applicationsets/expectation.go index 592ef34ef3907..e8be81b906d7e 100644 --- a/test/e2e/fixture/applicationsets/expectation.go +++ b/test/e2e/fixture/applicationsets/expectation.go @@ -192,10 +192,10 @@ func filterFields(input argov1alpha1.Application) argov1alpha1.Application { Finalizers: metaCopy.Finalizers, }, Spec: argov1alpha1.ApplicationSpec{ - Source: argov1alpha1.ApplicationSource{ - Path: spec.Source.Path, - RepoURL: spec.Source.RepoURL, - TargetRevision: spec.Source.TargetRevision, + Source: &argov1alpha1.ApplicationSource{ + Path: spec.GetSource().Path, + RepoURL: spec.GetSource().RepoURL, + TargetRevision: spec.GetSource().TargetRevision, }, Destination: argov1alpha1.ApplicationDestination{ Server: spec.Destination.Server, diff --git a/test/e2e/helm_test.go b/test/e2e/helm_test.go index 7c304a2e9e1de..318fad17d97eb 100644 --- a/test/e2e/helm_test.go +++ b/test/e2e/helm_test.go @@ -121,7 +121,7 @@ func TestHelmValues(t *testing.T) { AppSet("--values", "foo.yml"). Then(). And(func(app *Application) { - assert.Equal(t, []string{"foo.yml"}, app.Spec.Source.Helm.ValueFiles) + assert.Equal(t, []string{"foo.yml"}, app.Spec.GetSource().Helm.ValueFiles) }) } @@ -132,14 +132,14 @@ func TestHelmIgnoreMissingValueFiles(t *testing.T) { Declarative("declarative-apps/invalid-helm.yaml"). Then(). And(func(app *Application) { - assert.Equal(t, []string{"does-not-exist-values.yaml"}, app.Spec.Source.Helm.ValueFiles) - assert.Equal(t, false, app.Spec.Source.Helm.IgnoreMissingValueFiles) + assert.Equal(t, []string{"does-not-exist-values.yaml"}, app.Spec.GetSource().Helm.ValueFiles) + assert.Equal(t, false, app.Spec.GetSource().Helm.IgnoreMissingValueFiles) }). When(). AppSet("--ignore-missing-value-files"). Then(). And(func(app *Application) { - assert.Equal(t, true, app.Spec.Source.Helm.IgnoreMissingValueFiles) + assert.Equal(t, true, app.Spec.GetSource().Helm.IgnoreMissingValueFiles) }). When(). Sync(). @@ -151,7 +151,7 @@ func TestHelmIgnoreMissingValueFiles(t *testing.T) { AppUnSet("--ignore-missing-value-files"). Then(). And(func(app *Application) { - assert.Equal(t, false, app.Spec.Source.Helm.IgnoreMissingValueFiles) + assert.Equal(t, false, app.Spec.GetSource().Helm.IgnoreMissingValueFiles) }). When(). IgnoreErrors(). @@ -170,21 +170,21 @@ func TestHelmValuesMultipleUnset(t *testing.T) { AppSet("--values", "foo.yml", "--values", "baz.yml"). Then(). And(func(app *Application) { - assert.NotNil(t, app.Spec.Source.Helm) - assert.Equal(t, []string{"foo.yml", "baz.yml"}, app.Spec.Source.Helm.ValueFiles) + assert.NotNil(t, app.Spec.GetSource().Helm) + assert.Equal(t, []string{"foo.yml", "baz.yml"}, app.Spec.GetSource().Helm.ValueFiles) }). When(). AppUnSet("--values", "foo.yml"). Then(). And(func(app *Application) { - assert.NotNil(t, app.Spec.Source.Helm) - assert.Equal(t, []string{"baz.yml"}, app.Spec.Source.Helm.ValueFiles) + assert.NotNil(t, app.Spec.GetSource().Helm) + assert.Equal(t, []string{"baz.yml"}, app.Spec.GetSource().Helm.ValueFiles) }). When(). AppUnSet("--values", "baz.yml"). Then(). And(func(app *Application) { - assert.Nil(t, app.Spec.Source.Helm) + assert.Nil(t, app.Spec.GetSource().Helm) }) } @@ -200,13 +200,13 @@ func TestHelmValuesLiteralFileLocal(t *testing.T) { if err != nil { panic(err) } - assert.Equal(t, string(data), app.Spec.Source.Helm.Values) + assert.Equal(t, string(data), app.Spec.GetSource().Helm.Values) }). When(). AppUnSet("--values-literal"). Then(). And(func(app *Application) { - assert.Nil(t, app.Spec.Source.Helm) + assert.Nil(t, app.Spec.GetSource().Helm) }) } @@ -242,13 +242,13 @@ func TestHelmValuesLiteralFileRemote(t *testing.T) { AppSet("--values-literal-file", "http://"+address). Then(). And(func(app *Application) { - assert.Equal(t, "a: b", app.Spec.Source.Helm.Values) + assert.Equal(t, "a: b", app.Spec.GetSource().Helm.Values) }). When(). AppUnSet("--values-literal"). Then(). And(func(app *Application) { - assert.Nil(t, app.Spec.Source.Helm) + assert.Nil(t, app.Spec.GetSource().Helm) }) } @@ -274,7 +274,7 @@ func TestHelmReleaseName(t *testing.T) { AppSet("--release-name", "foo"). Then(). And(func(app *Application) { - assert.Equal(t, "foo", app.Spec.Source.Helm.ReleaseName) + assert.Equal(t, "foo", app.Spec.GetSource().Helm.ReleaseName) }) } @@ -286,7 +286,7 @@ func TestHelmSet(t *testing.T) { AppSet("--helm-set", "foo=bar", "--helm-set", "foo=baz", "--helm-set", "app=$ARGOCD_APP_NAME"). Then(). And(func(app *Application) { - assert.Equal(t, []HelmParameter{{Name: "foo", Value: "baz"}, {Name: "app", Value: "$ARGOCD_APP_NAME"}}, app.Spec.Source.Helm.Parameters) + assert.Equal(t, []HelmParameter{{Name: "foo", Value: "baz"}, {Name: "app", Value: "$ARGOCD_APP_NAME"}}, app.Spec.GetSource().Helm.Parameters) }) } @@ -298,7 +298,7 @@ func TestHelmSetString(t *testing.T) { AppSet("--helm-set-string", "foo=bar", "--helm-set-string", "foo=baz", "--helm-set-string", "app=$ARGOCD_APP_NAME"). Then(). And(func(app *Application) { - assert.Equal(t, []HelmParameter{{Name: "foo", Value: "baz", ForceString: true}, {Name: "app", Value: "$ARGOCD_APP_NAME", ForceString: true}}, app.Spec.Source.Helm.Parameters) + assert.Equal(t, []HelmParameter{{Name: "foo", Value: "baz", ForceString: true}, {Name: "app", Value: "$ARGOCD_APP_NAME", ForceString: true}}, app.Spec.GetSource().Helm.Parameters) }) } @@ -310,7 +310,7 @@ func TestHelmSetFile(t *testing.T) { AppSet("--helm-set-file", "foo=bar.yaml", "--helm-set-file", "foo=baz.yaml"). Then(). And(func(app *Application) { - assert.Equal(t, []HelmFileParameter{{Name: "foo", Path: "baz.yaml"}}, app.Spec.Source.Helm.FileParameters) + assert.Equal(t, []HelmFileParameter{{Name: "foo", Path: "baz.yaml"}}, app.Spec.GetSource().Helm.FileParameters) }) } diff --git a/test/e2e/kustomize_test.go b/test/e2e/kustomize_test.go index cb69d0c448a32..e6840e7b95eba 100644 --- a/test/e2e/kustomize_test.go +++ b/test/e2e/kustomize_test.go @@ -175,7 +175,7 @@ func TestKustomizeImages(t *testing.T) { AppSet("--kustomize-image", "alpine:foo", "--kustomize-image", "alpine:bar"). Then(). And(func(app *Application) { - assert.Contains(t, app.Spec.Source.Kustomize.Images, KustomizeImage("alpine:bar")) + assert.Contains(t, app.Spec.GetSource().Kustomize.Images, KustomizeImage("alpine:bar")) }) } @@ -188,7 +188,7 @@ func TestKustomizeNameSuffix(t *testing.T) { AppSet("--namesuffix", "-suf"). Then(). And(func(app *Application) { - assert.Contains(t, app.Spec.Source.Kustomize.NameSuffix, "-suf") + assert.Contains(t, app.Spec.GetSource().Kustomize.NameSuffix, "-suf") }) } @@ -201,25 +201,25 @@ func TestKustomizeUnsetOverride(t *testing.T) { AppSet("--namesuffix", "-suf"). Then(). And(func(app *Application) { - assert.Contains(t, app.Spec.Source.Kustomize.NameSuffix, "-suf") + assert.Contains(t, app.Spec.GetSource().Kustomize.NameSuffix, "-suf") }). When(). AppUnSet("--namesuffix"). Then(). And(func(app *Application) { - assert.Nil(t, app.Spec.Source.Kustomize) + assert.Nil(t, app.Spec.GetSource().Kustomize) }). When(). AppSet("--kustomize-image", "alpine:foo", "--kustomize-image", "alpine:bar"). Then(). And(func(app *Application) { - assert.Contains(t, app.Spec.Source.Kustomize.Images, KustomizeImage("alpine:bar")) + assert.Contains(t, app.Spec.GetSource().Kustomize.Images, KustomizeImage("alpine:bar")) }). When(). //AppUnSet("--kustomize-image=alpine"). AppUnSet("--kustomize-image", "alpine", "--kustomize-image", "alpine"). Then(). And(func(app *Application) { - assert.Nil(t, app.Spec.Source.Kustomize) + assert.Nil(t, app.Spec.GetSource().Kustomize) }) } diff --git a/test/e2e/matrix_e2e_test.go b/test/e2e/matrix_e2e_test.go index fe084806d8803..f6b923f24b7a4 100644 --- a/test/e2e/matrix_e2e_test.go +++ b/test/e2e/matrix_e2e_test.go @@ -27,7 +27,7 @@ func TestListMatrixGenerator(t *testing.T) { }, Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: argov1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: name, @@ -64,7 +64,7 @@ func TestListMatrixGenerator(t *testing.T) { ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{values.name}}-{{path.basename}}"}, Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: argov1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: "{{path}}", @@ -151,7 +151,7 @@ func TestClusterMatrixGenerator(t *testing.T) { }, Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: argov1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: name, @@ -190,7 +190,7 @@ func TestClusterMatrixGenerator(t *testing.T) { ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{name}}-{{path.basename}}"}, Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: argov1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: "{{path}}", diff --git a/test/e2e/merge_e2e_test.go b/test/e2e/merge_e2e_test.go index 96ab00621edb2..6a3de30f19f84 100644 --- a/test/e2e/merge_e2e_test.go +++ b/test/e2e/merge_e2e_test.go @@ -28,7 +28,7 @@ func TestListMergeGenerator(t *testing.T) { }, Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: argov1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: name, @@ -60,7 +60,7 @@ func TestListMergeGenerator(t *testing.T) { ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{path.basename}}-{{name-suffix}}"}, Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: argov1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: "{{path}}", @@ -148,7 +148,7 @@ func TestClusterMergeGenerator(t *testing.T) { }, Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: argov1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: name, @@ -187,7 +187,7 @@ func TestClusterMergeGenerator(t *testing.T) { ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{name}}-{{path.basename}}-{{values.name-suffix}}"}, Spec: argov1alpha1.ApplicationSpec{ Project: "default", - Source: argov1alpha1.ApplicationSource{ + Source: &argov1alpha1.ApplicationSource{ RepoURL: "https://github.com/argoproj/argocd-example-apps.git", TargetRevision: "HEAD", Path: "{{path}}", diff --git a/test/e2e/project_management_test.go b/test/e2e/project_management_test.go index dcc3affe7886d..b58906ac85bbc 100644 --- a/test/e2e/project_management_test.go +++ b/test/e2e/project_management_test.go @@ -329,7 +329,7 @@ func TestUseJWTToken(t *testing.T) { Name: appName, }, Spec: v1alpha1.ApplicationSpec{ - Source: v1alpha1.ApplicationSource{ + Source: &v1alpha1.ApplicationSource{ RepoURL: fixture.RepoURL(fixture.RepoURLTypeFile), Path: "guestbook", }, diff --git a/test/e2e/testdata/multiple-source-values/pod-1.yaml b/test/e2e/testdata/multiple-source-values/pod-1.yaml new file mode 100644 index 0000000000000..fa65ca29a4a80 --- /dev/null +++ b/test/e2e/testdata/multiple-source-values/pod-1.yaml @@ -0,0 +1,14 @@ +apiVersion: v1 +kind: Pod +metadata: + name: pod-1 + labels: + foo: bar +spec: + containers: + - name: main + image: quay.io/argoprojlabs/argocd-e2e-container:0.1 + imagePullPolicy: IfNotPresent + command: + - "true" + restartPolicy: Never diff --git a/test/e2e/testdata/multiple-source-values/values.yaml b/test/e2e/testdata/multiple-source-values/values.yaml new file mode 100644 index 0000000000000..71ffd9f273f08 --- /dev/null +++ b/test/e2e/testdata/multiple-source-values/values.yaml @@ -0,0 +1 @@ +replicas: 3 diff --git a/ui/src/app/applications/components/application-create-panel/application-create-panel.tsx b/ui/src/app/applications/components/application-create-panel/application-create-panel.tsx index f19761061aaa6..db87258b6bea3 100644 --- a/ui/src/app/applications/components/application-create-panel/application-create-panel.tsx +++ b/ui/src/app/applications/components/application-create-panel/application-create-panel.tsx @@ -11,6 +11,7 @@ import {ApplicationSyncOptionsField} from '../application-sync-options/applicati import {RevisionFormField} from '../revision-form-field/revision-form-field'; import {SetFinalizerOnApplication} from './set-finalizer-on-application'; import './application-create-panel.scss'; +import {getAppDefaultSource} from '../utils'; const jsonMergePatch = require('json-merge-patch'); @@ -38,6 +39,7 @@ const DEFAULT_APP: Partial = { repoURL: '', targetRevision: 'HEAD' }, + sources: [], project: '' } }; @@ -79,16 +81,17 @@ const AutoSyncFormField = ReactFormField((props: {fieldApi: FieldApi; className: }); function normalizeAppSource(app: models.Application, type: string): boolean { - const repoType = (app.spec.source.hasOwnProperty('chart') && 'helm') || 'git'; + const source = getAppDefaultSource(app); + const repoType = (source.hasOwnProperty('chart') && 'helm') || 'git'; if (repoType !== type) { if (type === 'git') { - app.spec.source.path = app.spec.source.chart; - delete app.spec.source.chart; - app.spec.source.targetRevision = 'HEAD'; + source.path = source.chart; + delete source.chart; + source.targetRevision = 'HEAD'; } else { - app.spec.source.chart = app.spec.source.path; - delete app.spec.source.path; - app.spec.source.targetRevision = ''; + source.chart = source.path; + delete source.path; + source.targetRevision = ''; } return true; } diff --git a/ui/src/app/applications/components/application-details/application-details.tsx b/ui/src/app/applications/components/application-details/application-details.tsx index 930faff48e653..b6c0d9d13ade7 100644 --- a/ui/src/app/applications/components/application-details/application-details.tsx +++ b/ui/src/app/applications/components/application-details/application-details.tsx @@ -24,7 +24,7 @@ import {ResourceDetails} from '../resource-details/resource-details'; import * as AppUtils from '../utils'; import {ApplicationResourceList} from './application-resource-list'; import {Filters, FiltersProps} from './application-resource-filter'; -import {urlPattern} from '../utils'; +import {getAppDefaultSource, urlPattern} from '../utils'; import {ResourceStatus} from '../../../shared/models'; import {ApplicationsDetailsAppDropdown} from './application-details-app-dropdown'; import {useSidebarTarget} from '../../../sidebar/sidebar'; @@ -195,7 +195,7 @@ export class ApplicationDetails extends React.Component { const statusByKey = new Map(); application.status.resources.forEach(res => statusByKey.set(AppUtils.nodeKey(res), res)); @@ -560,7 +560,7 @@ export class ApplicationDetails extends React.Component
SHA:
- +
diff --git a/ui/src/app/applications/components/application-operation-state/application-operation-state.tsx b/ui/src/app/applications/components/application-operation-state/application-operation-state.tsx index 65edd42db41ff..0f5bbac2615a2 100644 --- a/ui/src/app/applications/components/application-operation-state/application-operation-state.tsx +++ b/ui/src/app/applications/components/application-operation-state/application-operation-state.tsx @@ -93,7 +93,7 @@ export const ApplicationOperationState: React.StatelessComponent = ({appl }); } if (operationState.syncResult) { - operationAttributes.push({title: 'REVISION', value: }); + operationAttributes.push({title: 'REVISION', value: }); } let initiator = ''; if (operationState.operation.initiatedBy) { diff --git a/ui/src/app/applications/components/application-parameters/application-parameters.tsx b/ui/src/app/applications/components/application-parameters/application-parameters.tsx index d621ec4af2db2..4ffdd86d5153e 100644 --- a/ui/src/app/applications/components/application-parameters/application-parameters.tsx +++ b/ui/src/app/applications/components/application-parameters/application-parameters.tsx @@ -10,6 +10,7 @@ import {ImageTagFieldEditor} from './kustomize'; import * as kustomize from './kustomize-image'; import {VarsInputField} from './vars-input-field'; import {concatMaps} from '../../../shared/utils'; +import {getAppDefaultSource} from '../utils'; const TextWithMetadataField = ReactFormField((props: {metadata: {value: string}; fieldApi: FieldApi; className: string}) => { const { @@ -112,7 +113,7 @@ export const ApplicationParameters = (props: { noReadonlyMode?: boolean; }) => { const app = props.application; - const source = props.application.spec.source; + const source = getAppDefaultSource(app); const [removedOverrides, setRemovedOverrides] = React.useState(new Array()); let attributes: EditablePanelItem[] = []; @@ -120,7 +121,7 @@ export const ApplicationParameters = (props: { if (props.details.type === 'Kustomize' && props.details.kustomize) { attributes.push({ title: 'VERSION', - view: (app.spec.source.kustomize && app.spec.source.kustomize.version) || default, + view: (source.kustomize && source.kustomize.version) || default, edit: (formApi: FormApi) => ( services.authService.settings()}> {settings => @@ -134,13 +135,13 @@ export const ApplicationParameters = (props: { attributes.push({ title: 'NAME PREFIX', - view: app.spec.source.kustomize && app.spec.source.kustomize.namePrefix, + view: source.kustomize && source.kustomize.namePrefix, edit: (formApi: FormApi) => }); attributes.push({ title: 'NAME SUFFIX', - view: app.spec.source.kustomize && app.spec.source.kustomize.nameSuffix, + view: source.kustomize && source.kustomize.nameSuffix, edit: (formApi: FormApi) => }); @@ -178,7 +179,7 @@ export const ApplicationParameters = (props: { } else if (props.details.type === 'Helm' && props.details.helm) { attributes.push({ title: 'VALUES FILES', - view: (app.spec.source.helm && (app.spec.source.helm.valueFiles || []).join(', ')) || 'No values files selected', + view: (source.helm && (source.helm.valueFiles || []).join(', ')) || 'No values files selected', edit: (formApi: FormApi) => ( ) }); - if (app?.spec?.source?.helm?.values) { + if (source?.helm?.values) { attributes.push({ title: 'VALUES', - view: app.spec.source.helm && ( + view: source.helm && ( -
{app.spec.source.helm.values}
+
{source.helm.values}
), edit: (formApi: FormApi) => ( @@ -265,7 +266,7 @@ export const ApplicationParameters = (props: { } else if (props.details.type === 'Plugin') { attributes.push({ title: 'NAME', - view: app.spec.source.plugin && app.spec.source.plugin.name, + view: source.plugin && source.plugin.name, edit: (formApi: FormApi) => ( services.authService.settings()}> {(settings: AuthSettings) => ( @@ -276,7 +277,7 @@ export const ApplicationParameters = (props: { }); attributes.push({ title: 'ENV', - view: app.spec.source.plugin && (app.spec.source.plugin.env || []).map(i => `${i.name}='${i.value}'`).join(' '), + view: source.plugin && (source.plugin.env || []).map(i => `${i.name}='${i.value}'`).join(' '), edit: (formApi: FormApi) => }); if (props.details.plugin.parametersAnnouncement) { @@ -310,7 +311,7 @@ export const ApplicationParameters = (props: { } } } else if (props.details.type === 'Directory') { - const directory = app.spec.source.directory || ({} as ApplicationSourceDirectory); + const directory = source.directory || ({} as ApplicationSourceDirectory); attributes.push({ title: 'DIRECTORY RECURSE', view: (!!directory.recurse).toString(), @@ -318,7 +319,7 @@ export const ApplicationParameters = (props: { }); attributes.push({ title: 'TOP-LEVEL ARGUMENTS', - view: ((directory.jsonnet && directory.jsonnet.tlas) || []).map((i, j) => ( + view: ((directory?.jsonnet && directory?.jsonnet.tlas) || []).map((i, j) => ( @@ -337,13 +338,13 @@ export const ApplicationParameters = (props: { attributes.push({ title: 'INCLUDE', - view: app.spec.source.directory && app.spec.source.directory.include, + view: directory && directory.include, edit: (formApi: FormApi) => }); attributes.push({ title: 'EXCLUDE', - view: app.spec.source.directory && app.spec.source.directory.exclude, + view: directory && directory.exclude, edit: (formApi: FormApi) => }); } @@ -353,6 +354,7 @@ export const ApplicationParameters = (props: { save={ props.save && (async (input: models.Application) => { + const src = getAppDefaultSource(input); function isDefined(item: any) { return item !== null && item !== undefined; } @@ -360,11 +362,11 @@ export const ApplicationParameters = (props: { return item !== null && item !== undefined && item.match(/:/); } - if (input.spec.source.helm && input.spec.source.helm.parameters) { - input.spec.source.helm.parameters = input.spec.source.helm.parameters.filter(isDefined); + if (src.helm && src.helm.parameters) { + src.helm.parameters = src.helm.parameters.filter(isDefined); } - if (input.spec.source.kustomize && input.spec.source.kustomize.images) { - input.spec.source.kustomize.images = input.spec.source.kustomize.images.filter(isDefinedWithVersion); + if (src.kustomize && src.kustomize.images) { + src.kustomize.images = src.kustomize.images.filter(isDefinedWithVersion); } await props.save(input, {}); setRemovedOverrides(new Array()); diff --git a/ui/src/app/applications/components/application-status-panel/application-status-panel.tsx b/ui/src/app/applications/components/application-status-panel/application-status-panel.tsx index 9bbb233701b88..443a841f5785f 100644 --- a/ui/src/app/applications/components/application-status-panel/application-status-panel.tsx +++ b/ui/src/app/applications/components/application-status-panel/application-status-panel.tsx @@ -5,7 +5,8 @@ import {Revision} from '../../../shared/components/revision'; import {Timestamp} from '../../../shared/components/timestamp'; import * as models from '../../../shared/models'; import {services} from '../../../shared/services'; -import {ApplicationSyncWindowStatusIcon, ComparisonStatusIcon, getAppOperationState, getConditionCategory, HealthStatusIcon, OperationState, syncStatusMessage} from '../utils'; +import {ApplicationSyncWindowStatusIcon, ComparisonStatusIcon, getAppDefaultSource, getAppOperationState} from '../utils'; +import {getConditionCategory, HealthStatusIcon, OperationState, syncStatusMessage} from '../utils'; import {RevisionMetadataPanel} from './revision-metadata-panel'; import './application-status-panel.scss'; @@ -63,7 +64,7 @@ export const ApplicationStatusPanel = ({application, showOperation, showConditio const infos = cntByCategory.get('info'); const warnings = cntByCategory.get('warning'); const errors = cntByCategory.get('error'); - + const source = getAppDefaultSource(application); return (
@@ -82,7 +83,7 @@ export const ApplicationStatusPanel = ({application, showOperation, showConditio title: 'CURRENT SYNC STATUS', helpContent: 'Whether or not the version of your app is up to date with your repo. You may wish to sync your app if it is out-of-sync.' }, - application.spec.source.chart ? null : () => showMetadataInfo(application.status.sync ? application.status.sync.revision : '') + source.chart ? null : () => showMetadataInfo(application.status.sync ? application.status.sync.revision : '') )}
@@ -95,7 +96,7 @@ export const ApplicationStatusPanel = ({application, showOperation, showConditio
@@ -114,7 +115,7 @@ export const ApplicationStatusPanel = ({application, showOperation, showConditio daysSinceLastSynchronized + ' days since last sync. Click for the status of that sync.' }, - application.spec.source.chart ? null : () => showMetadataInfo(appOperationState.syncResult ? appOperationState.syncResult.revision : '') + source.chart ? null : () => showMetadataInfo(appOperationState.syncResult ? appOperationState.syncResult.revision : '') )} @@ -134,7 +135,7 @@ export const ApplicationStatusPanel = ({application, showOperation, showConditio )) ||
{appOperationState.message}
} diff --git a/ui/src/app/applications/components/application-summary/application-summary.tsx b/ui/src/app/applications/components/application-summary/application-summary.tsx index f4bf986ba19d9..9ba867183bdb8 100644 --- a/ui/src/app/applications/components/application-summary/application-summary.tsx +++ b/ui/src/app/applications/components/application-summary/application-summary.tsx @@ -21,7 +21,7 @@ import {services} from '../../../shared/services'; import {ApplicationSyncOptionsField} from '../application-sync-options/application-sync-options'; import {RevisionFormField} from '../revision-form-field/revision-form-field'; -import {ComparisonStatusIcon, HealthStatusIcon, syncStatusMessage, urlPattern, formatCreationTimestamp} from '../utils'; +import {ComparisonStatusIcon, HealthStatusIcon, syncStatusMessage, urlPattern, formatCreationTimestamp, getAppDefaultSource, getAppSpecDefaultSource} from '../utils'; import {ApplicationRetryOptions} from '../application-retry-options/application-retry-options'; import {ApplicationRetryView} from '../application-retry-view/application-retry-view'; import {Link} from 'react-router-dom'; @@ -44,7 +44,8 @@ export interface ApplicationSummaryProps { export const ApplicationSummary = (props: ApplicationSummaryProps) => { const app = JSON.parse(JSON.stringify(props.app)) as models.Application; - const isHelm = app.spec.source.hasOwnProperty('chart'); + const source = getAppDefaultSource(app); + const isHelm = source.hasOwnProperty('chart'); const initialState = app.spec.destination.server === undefined ? 'NAME' : 'URL'; const [destFormat, setDestFormat] = React.useState(initialState); const [changeSync, setChangeSync] = React.useState(false); @@ -157,7 +158,7 @@ export const ApplicationSummary = (props: ApplicationSummaryProps) => { }, { title: 'REPO URL', - view: , + view: , edit: (formApi: FormApi) => }, ...(isHelm @@ -166,12 +167,12 @@ export const ApplicationSummary = (props: ApplicationSummaryProps) => { title: 'CHART', view: ( - {app.spec.source.chart}:{app.spec.source.targetRevision} + {source.chart}:{source.targetRevision} ), edit: (formApi: FormApi) => ( services.repos.charts(src.repoURL).catch(() => new Array())}> {(charts: models.HelmChart[]) => (
@@ -187,7 +188,7 @@ export const ApplicationSummary = (props: ApplicationSummaryProps) => { />
{ const chartInfo = data.charts.find(chart => chart.name === data.chart); return (chartInfo && chartInfo.versions) || new Array(); @@ -215,14 +216,14 @@ export const ApplicationSummary = (props: ApplicationSummaryProps) => { : [ { title: 'TARGET REVISION', - view: , - edit: (formApi: FormApi) => + view: , + edit: (formApi: FormApi) => }, { title: 'PATH', view: ( - - {app.spec.source.path} + + {source.path} ), edit: (formApi: FormApi) => @@ -454,11 +455,11 @@ export const ApplicationSummary = (props: ApplicationSummaryProps) => { return (
- {app.spec.source.plugin && typeof app.spec.source.plugin.name === 'string' && app.spec.source.plugin.name !== '' && ( + {source.plugin && typeof source.plugin.name === 'string' && source.plugin.name !== '' && (
This Application uses a plugin which will no longer be supported starting with - Argo CD version 2.6. Contact your Argo CD administrator to make sure they upgrade the '{app.spec.source.plugin.name}' plugin before upgrading to Argo CD 2.6. - See the 2.4-to-2.5 upgrade notes for details. + Argo CD version 2.6. Contact your Argo CD administrator to make sure they upgrade the '{source.plugin.name}' plugin before upgrading to Argo CD 2.6. See the{' '} + 2.4-to-2.5 upgrade notes for details.
)} nodeKey(item) === selectedResource); const syncStrategy = {} as models.SyncStrategy; const [isPending, setPending] = React.useState(false); + const source = getAppDefaultSource(application); return ( @@ -47,7 +48,7 @@ export const ApplicationSyncPanel = ({application, selectedResource, hide}: {app {isVisible && (
i === syncResIndex || syncResIndex === -1), syncOptions: application.spec.syncPolicy ? application.spec.syncPolicy.syncOptions : [] }} @@ -119,7 +120,7 @@ export const ApplicationSyncPanel = ({application, selectedResource, hide}: {app {formApi => (
- Synchronizing application manifests from {application.spec.source.repoURL} + Synchronizing application manifests from {source.repoURL}
diff --git a/ui/src/app/applications/components/applications-list/applications-filter.tsx b/ui/src/app/applications/components/applications-list/applications-filter.tsx index 6d50b7c65abf6..4d6e9d78c631d 100644 --- a/ui/src/app/applications/components/applications-list/applications-filter.tsx +++ b/ui/src/app/applications/components/applications-list/applications-filter.tsx @@ -6,7 +6,7 @@ import {Application, ApplicationDestination, Cluster, HealthStatusCode, HealthSt import {AppsListPreferences, services} from '../../../shared/services'; import {Filter, FiltersGroup} from '../filter/filter'; import * as LabelSelector from '../label-selector'; -import {ComparisonStatusIcon, HealthStatusIcon} from '../utils'; +import {ComparisonStatusIcon, getAppDefaultSource, HealthStatusIcon} from '../utils'; export interface FilterResult { repos: boolean; @@ -34,7 +34,7 @@ export function getFilterResults(applications: Application[], pref: AppsListPref return applications.map(app => ({ ...app, filterResult: { - repos: pref.reposFilter.length === 0 || pref.reposFilter.includes(app.spec.source.repoURL), + repos: pref.reposFilter.length === 0 || pref.reposFilter.includes(getAppDefaultSource(app).repoURL), sync: pref.syncFilter.length === 0 || pref.syncFilter.includes(app.status.sync.status), autosync: pref.autoSyncFilter.length === 0 || pref.autoSyncFilter.includes(getAutoSyncStatus(app.spec.syncPolicy)), health: pref.healthFilter.length === 0 || pref.healthFilter.includes(app.status.health.status), diff --git a/ui/src/app/applications/components/applications-list/applications-labels.tsx b/ui/src/app/applications/components/applications-list/applications-labels.tsx index 523994f08a097..3f401f452e107 100644 --- a/ui/src/app/applications/components/applications-list/applications-labels.tsx +++ b/ui/src/app/applications/components/applications-list/applications-labels.tsx @@ -1,13 +1,14 @@ import * as React from 'react'; import {Tooltip} from 'argo-ui'; import {Application} from '../../../shared/models'; +import {getAppDefaultSource} from '../utils'; import './applications-labels.scss'; export const ApplicationsLabels = ({app}: {app: Application}) => { const labels = ( <> - {app.spec.source.targetRevision || 'HEAD'} + {getAppDefaultSource(app).targetRevision || 'HEAD'} {Object.keys(app.metadata.labels || {}).map(label => ( {`${label}=${app.metadata.labels[label]}`} ))} diff --git a/ui/src/app/applications/components/applications-list/applications-table.tsx b/ui/src/app/applications/components/applications-list/applications-table.tsx index 2996b7af7e156..c3b0fa9dd9350 100644 --- a/ui/src/app/applications/components/applications-list/applications-table.tsx +++ b/ui/src/app/applications/components/applications-list/applications-table.tsx @@ -7,7 +7,7 @@ import {Consumer, Context} from '../../../shared/context'; import * as models from '../../../shared/models'; import {ApplicationURLs} from '../application-urls'; import * as AppUtils from '../utils'; -import {OperationState} from '../utils'; +import {getAppDefaultSource, OperationState} from '../utils'; import {ApplicationsLabels} from './applications-labels'; import {ApplicationsSource} from './applications-source'; import {services} from '../../../shared/services'; @@ -114,7 +114,7 @@ export const ApplicationsTable = (props: {
Source:
- +
diff --git a/ui/src/app/applications/components/applications-list/applications-tiles.tsx b/ui/src/app/applications/components/applications-list/applications-tiles.tsx index e77cc817250a7..cf54bf38fc862 100644 --- a/ui/src/app/applications/components/applications-list/applications-tiles.tsx +++ b/ui/src/app/applications/components/applications-list/applications-tiles.tsx @@ -7,7 +7,7 @@ import {Consumer, Context, AuthSettingsCtx} from '../../../shared/context'; import * as models from '../../../shared/models'; import {ApplicationURLs} from '../application-urls'; import * as AppUtils from '../utils'; -import {OperationState} from '../utils'; +import {getAppDefaultSource, OperationState} from '../utils'; import {services} from '../../../shared/services'; import './applications-tiles.scss'; @@ -108,200 +108,207 @@ export const ApplicationTiles = ({applications, syncApplication, refreshApplicat
- {applications.map((app, i) => ( -
-
+ {applications.map((app, i) => { + const source = getAppDefaultSource(app); + return ( +
- ctx.navigation.goto(`/applications/${app.metadata.namespace}/${app.metadata.name}`, {view: pref.appDetails.view}, {event: e}) - }> -
-
-
0 - ? 'columns small-10' - : 'columns small-11' - }> - - - - {AppUtils.appQualifiedName(app, useAuthSettingsCtx?.appsInAnyNamespaceEnabled)} - - -
-
0 - ? 'columns small-2' - : 'columns small-1' - }> -
- - - + ref={appRef.set ? null : appRef.ref} + className={`argo-table-list__row applications-list__entry applications-list__entry--health-${app.status.health.status} ${ + selectedApp === i ? 'applications-tiles__selected' : '' + }`}> +
+ ctx.navigation.goto( + `/applications/${app.metadata.namespace}/${app.metadata.name}`, + {view: pref.appDetails.view}, + {event: e} + ) + }> +
+
+
0 + ? 'columns small-10' + : 'columns small-11' + }> + + + + {AppUtils.appQualifiedName(app, useAuthSettingsCtx?.appsInAnyNamespaceEnabled)} +
-
-
-
-
- Project: -
-
{app.spec.project}
-
-
-
- Labels: -
-
- - {Object.keys(app.metadata.labels || {}) - .map(label => ({label, value: app.metadata.labels[label]})) - .map(item => ( -
- {item.label}={item.value} -
- ))} -
+
0 + ? 'columns small-2' + : 'columns small-1' }> - - {Object.keys(app.metadata.labels || {}) - .map(label => `${label}=${app.metadata.labels[label]}`) - .join(', ')} - - -
-
-
-
- Status: -
-
- {app.status.health.status} -   - {app.status.sync.status} -   - -
-
-
-
- Repository: +
+ + + + +
+
-
- - {app.spec.source.repoURL} - +
+
+ Project: +
+
{app.spec.project}
-
-
-
- Target Revision: +
+
+ Labels: +
+
+ + {Object.keys(app.metadata.labels || {}) + .map(label => ({label, value: app.metadata.labels[label]})) + .map(item => ( +
+ {item.label}={item.value} +
+ ))} +
+ }> + + {Object.keys(app.metadata.labels || {}) + .map(label => `${label}=${app.metadata.labels[label]}`) + .join(', ')} + + +
-
{app.spec.source.targetRevision || 'HEAD'}
-
- {app.spec.source.path && (
-
- Path: +
+ Status: +
+
+ {app.status.health.status} +   + {app.status.sync.status} +   +
-
{app.spec.source.path}
- )} - {app.spec.source.chart && (
-
- Chart: +
+ Repository: +
+
+ + {source.repoURL} +
-
{app.spec.source.chart}
- )} -
-
- Destination: +
+
+ Target Revision: +
+
{source.targetRevision || 'HEAD'}
-
- + {source.path && ( +
+
+ Path: +
+
{source.path}
+
+ )} + {source.chart && ( +
+
+ Chart: +
+
{source.chart}
+
+ )} +
+
+ Destination: +
+
+ +
-
-
-
- Namespace: +
+
+ Namespace: +
+
{app.spec.destination.namespace}
-
{app.spec.destination.namespace}
-
-
-
- Created At: +
+
+ Created At: +
+
{AppUtils.formatCreationTimestamp(app.metadata.creationTimestamp)}
-
{AppUtils.formatCreationTimestamp(app.metadata.creationTimestamp)}
-
-
-
- ))} + ); + })}
); }} diff --git a/ui/src/app/applications/components/applications-sync-panel/applications-sync-panel.tsx b/ui/src/app/applications/components/applications-sync-panel/applications-sync-panel.tsx index 71d2f4c512421..0c97b75eb0b70 100644 --- a/ui/src/app/applications/components/applications-sync-panel/applications-sync-panel.tsx +++ b/ui/src/app/applications/components/applications-sync-panel/applications-sync-panel.tsx @@ -8,7 +8,7 @@ import {services} from '../../../shared/services'; import {ApplicationRetryOptions} from '../application-retry-options/application-retry-options'; import {ApplicationManualSyncFlags, ApplicationSyncOptions, FORCE_WARNING, SyncFlags} from '../application-sync-options/application-sync-options'; import {ApplicationSelector} from '../../../shared/components'; -import {confirmSyncingAppOfApps} from '../utils'; +import {confirmSyncingAppOfApps, getAppDefaultSource} from '../utils'; interface Progress { percentage: number; @@ -99,7 +99,7 @@ export const ApplicationsSyncPanel = ({show, apps, hide}: {show: boolean; apps: .sync( app.metadata.name, app.metadata.namespace, - app.spec.source.targetRevision, + getAppDefaultSource(app).targetRevision, syncFlags.Prune || false, syncFlags.DryRun || false, syncStrategy, diff --git a/ui/src/app/applications/components/resource-details/resource-details.tsx b/ui/src/app/applications/components/resource-details/resource-details.tsx index 1166ebff22378..2fd8b76e71b06 100644 --- a/ui/src/app/applications/components/resource-details/resource-details.tsx +++ b/ui/src/app/applications/components/resource-details/resource-details.tsx @@ -172,9 +172,9 @@ export const ResourceDetails = (props: ResourceDetailsProps) => { key='appDetails' input={application} load={app => - services.repos.appDetails(app.spec.source, app.metadata.name, app.spec.project).catch(() => ({ + services.repos.appDetails(AppUtils.getAppDefaultSource(app), app.metadata.name, app.spec.project).catch(() => ({ type: 'Directory' as AppSourceType, - path: application.spec.source.path + path: AppUtils.getAppDefaultSource(app).path })) }> {(details: RepoAppDetails) => ( diff --git a/ui/src/app/applications/components/utils.tsx b/ui/src/app/applications/components/utils.tsx index e7abc74310fc3..cd81693474dd1 100644 --- a/ui/src/app/applications/components/utils.tsx +++ b/ui/src/app/applications/components/utils.tsx @@ -629,12 +629,14 @@ export function renderResourceButtons( } export function syncStatusMessage(app: appModels.Application) { - const rev = app.status.sync.revision || app.spec.source.targetRevision || 'HEAD'; - let message = app.spec.source.targetRevision || 'HEAD'; + const source = getAppDefaultSource(app); + const rev = app.status.sync.revision || source.targetRevision || 'HEAD'; + let message = source.targetRevision || 'HEAD'; + if (app.status.sync.revision) { - if (app.spec.source.chart) { + if (source.chart) { message += ' (' + app.status.sync.revision + ')'; - } else if (app.status.sync.revision.length >= 7 && !app.status.sync.revision.startsWith(app.spec.source.targetRevision)) { + } else if (app.status.sync.revision.length >= 7 && !app.status.sync.revision.startsWith(source.targetRevision)) { message += ' (' + app.status.sync.revision.substr(0, 7) + ')'; } } @@ -643,7 +645,7 @@ export function syncStatusMessage(app: appModels.Application) { return ( To{' '} - + {message} {' '} @@ -652,7 +654,7 @@ export function syncStatusMessage(app: appModels.Application) { return ( From{' '} - + {message} {' '} @@ -975,15 +977,29 @@ export function isAppNode(node: appModels.ResourceNode) { } export function getAppOverridesCount(app: appModels.Application) { - if (app.spec.source.kustomize && app.spec.source.kustomize.images) { - return app.spec.source.kustomize.images.length; + const source = getAppDefaultSource(app); + if (source.kustomize && source.kustomize.images) { + return source.kustomize.images.length; } - if (app.spec.source.helm && app.spec.source.helm.parameters) { - return app.spec.source.helm.parameters.length; + if (source.helm && source.helm.parameters) { + return source.helm.parameters.length; } return 0; } +// getAppDefaultSource gets the first app source from `sources` or, if that list is missing or empty, the `source` +// field. +export function getAppDefaultSource(app?: appModels.Application) { + if (!app) { + return null; + } + return app.spec.sources && app.spec.sources.length > 0 ? app.spec.sources[0] : app.spec.source; +} + +export function getAppSpecDefaultSource(spec: appModels.ApplicationSpec) { + return spec.sources && spec.sources.length > 0 ? spec.sources[0] : spec.source; +} + export function isAppRefreshing(app: appModels.Application) { return !!(app.metadata.annotations && app.metadata.annotations[appModels.AnnotationRefreshKey]); } diff --git a/ui/src/app/shared/models.ts b/ui/src/app/shared/models.ts index 37ec6b44ddbcc..3bbaed2ba4226 100644 --- a/ui/src/app/shared/models.ts +++ b/ui/src/app/shared/models.ts @@ -259,6 +259,7 @@ export interface Info { export interface ApplicationSpec { project: string; source: ApplicationSource; + sources: ApplicationSource[]; destination: ApplicationDestination; syncPolicy?: SyncPolicy; ignoreDifferences?: ResourceIgnoreDifferences[]; @@ -282,6 +283,8 @@ export interface RevisionHistory { id: number; revision: string; source: ApplicationSource; + revisions: string[]; + sources: ApplicationSource[]; deployStartedAt: models.Time; deployedAt: models.Time; } @@ -387,6 +390,7 @@ export interface SyncStatus { comparedTo: ApplicationSource; status: SyncStatusCode; revision: string; + revisions: string[]; } export interface ApplicationCondition { diff --git a/util/argo/argo.go b/util/argo/argo.go index 1c5a2c2040ca0..b8535e20ec6c0 100644 --- a/util/argo/argo.go +++ b/util/argo/argo.go @@ -4,6 +4,7 @@ import ( "context" "encoding/json" "fmt" + "regexp" "sort" "strings" "time" @@ -87,7 +88,7 @@ func FilterByRepo(apps []argoappv1.Application, repo string) []argoappv1.Applica } items := make([]argoappv1.Application, 0) for i := 0; i < len(apps); i++ { - if apps[i].Spec.Source.RepoURL == repo { + if apps[i].Spec.GetSource().RepoURL == repo { items = append(items, apps[i]) } } @@ -180,13 +181,13 @@ func ValidateRepo( app *argoappv1.Application, repoClientset apiclient.Clientset, db db.ArgoDB, - kustomizeOptions *argoappv1.KustomizeOptions, plugins []*argoappv1.ConfigManagementPlugin, kubectl kube.Kubectl, proj *argoappv1.AppProject, settingsMgr *settings.SettingsManager, ) ([]argoappv1.ApplicationCondition, error) { spec := &app.Spec + conditions := make([]argoappv1.ApplicationCondition, 0) // Test the repo @@ -195,33 +196,6 @@ func ValidateRepo( return nil, fmt.Errorf("error instantiating new repo server client: %w", err) } defer io.Close(conn) - repo, err := db.GetRepository(ctx, spec.Source.RepoURL) - if err != nil { - return nil, fmt.Errorf("error getting repository: %w", err) - } - - repoAccessible := false - - err = TestRepoWithKnownType(ctx, repoClient, repo, app.Spec.Source.IsHelm(), app.Spec.Source.IsHelmOci()) - if err != nil { - conditions = append(conditions, argoappv1.ApplicationCondition{ - Type: argoappv1.ApplicationConditionInvalidSpecError, - Message: fmt.Sprintf("repository not accessible: %v", err), - }) - } else { - repoAccessible = true - } - - // Verify only one source type is defined - _, err = spec.Source.ExplicitType() - if err != nil { - return nil, fmt.Errorf("error verifying source type: %w", err) - } - - // is the repo inaccessible - abort now - if !repoAccessible { - return conditions, nil - } helmOptions, err := settingsMgr.GetHelmSettings() if err != nil { @@ -266,24 +240,144 @@ func ValidateRepo( if err != nil { return nil, fmt.Errorf("error getting enabled source types: %w", err) } + + sourceCondition, err := validateRepo( + ctx, + app, + db, + app.Spec.GetSources(), + repoClient, + plugins, + permittedHelmRepos, + helmOptions, + cluster, + apiGroups, + proj, + permittedHelmCredentials, + enabledSourceTypes, + settingsMgr) + if err != nil { + return nil, err + } + conditions = append(conditions, sourceCondition...) + + return conditions, nil +} + +func validateRepo(ctx context.Context, + app *argoappv1.Application, + db db.ArgoDB, + sources []argoappv1.ApplicationSource, + repoClient apiclient.RepoServerServiceClient, + plugins []*argoappv1.ConfigManagementPlugin, + permittedHelmRepos []*argoappv1.Repository, + helmOptions *argoappv1.HelmOptions, + cluster *argoappv1.Cluster, + apiGroups []kube.APIResourceInfo, + proj *argoappv1.AppProject, + permittedHelmCredentials []*argoappv1.RepoCreds, + enabledSourceTypes map[string]bool, + settingsMgr *settings.SettingsManager, +) ([]argoappv1.ApplicationCondition, error) { + conditions := make([]argoappv1.ApplicationCondition, 0) + errMessage := "" + + for _, source := range sources { + repo, err := db.GetRepository(ctx, source.RepoURL) + if err != nil { + return nil, err + } + if err := TestRepoWithKnownType(ctx, repoClient, repo, source.IsHelm(), source.IsHelmOci()); err != nil { + errMessage = fmt.Sprintf("repositories not accessible: %v", repo) + } + repoAccessible := false + + if errMessage != "" { + conditions = append(conditions, argoappv1.ApplicationCondition{ + Type: argoappv1.ApplicationConditionInvalidSpecError, + Message: fmt.Sprintf("repository not accessible: %v", errMessage), + }) + } else { + repoAccessible = true + } + + // Verify only one source type is defined + _, err = source.ExplicitType() + if err != nil { + return nil, fmt.Errorf("error verifying source type: %w", err) + } + + // is the repo inaccessible - abort now + if !repoAccessible { + return conditions, nil + } + } + + refSources, err := GetRefSources(ctx, app.Spec, db) + if err != nil { + return nil, fmt.Errorf("error getting ref sources: %w", err) + } conditions = append(conditions, verifyGenerateManifests( ctx, - repo, + db, permittedHelmRepos, helmOptions, - app, + app.Name, + app.Spec.Destination, + sources, repoClient, - kustomizeOptions, plugins, cluster.ServerVersion, APIResourcesToStrings(apiGroups, true), permittedHelmCredentials, enabledSourceTypes, - settingsMgr)...) + settingsMgr, + app.Spec.HasMultipleSources(), + refSources)...) return conditions, nil } +// GetRefSources creates a map of ref keys (from the sources' 'ref' fields) to information about the referenced source. +// This function also validates the references use allowed characters and does not define the same ref key more than +// once (which would lead to ambiguous references). +func GetRefSources(ctx context.Context, spec argoappv1.ApplicationSpec, db db.ArgoDB) (argoappv1.RefTargetRevisionMapping, error) { + refSources := make(argoappv1.RefTargetRevisionMapping) + if spec.HasMultipleSources() { + // Validate first to avoid unnecessary DB calls. + refKeys := make(map[string]bool) + for _, source := range spec.Sources { + if source.Ref != "" { + isValidRefKey := regexp.MustCompile(`^[a-zA-Z0-9]+$`).MatchString + if !isValidRefKey(source.Ref) { + return nil, fmt.Errorf("source.ref %s cannot contain any special characters except '_' and '-'", source.Ref) + } + refKey := "$" + source.Ref + if _, ok := refKeys[refKey]; ok { + return nil, fmt.Errorf("invalid sources: multiple sources had the same `ref` key") + } + refKeys[refKey] = true + } + } + // Get Repositories for all sources before generating Manifests + for _, source := range spec.Sources { + if source.Ref != "" { + repo, err := db.GetRepository(ctx, source.RepoURL) + if err != nil { + return nil, fmt.Errorf("failed to get repository %s: %v", source.RepoURL, err) + } + refKey := "$" + source.Ref + refSources[refKey] = &argoappv1.RefTarget{ + Repo: *repo, + TargetRevision: source.TargetRevision, + Chart: source.Chart, + } + } + } + } + return refSources, nil +} + // ValidateDestination sets the 'Server' value of the ApplicationDestination, if it is not set. // NOTE: this function WILL write to the object pointed to by the 'dest' parameter. // @@ -313,29 +407,68 @@ func ValidateDestination(ctx context.Context, dest *argoappv1.ApplicationDestina return nil } -// ValidatePermissions ensures that the referenced cluster has been added to Argo CD and the app source repo and destination namespace/cluster are permitted in app project -func ValidatePermissions(ctx context.Context, spec *argoappv1.ApplicationSpec, proj *argoappv1.AppProject, db db.ArgoDB) ([]argoappv1.ApplicationCondition, error) { - conditions := make([]argoappv1.ApplicationCondition, 0) - if spec.Source.RepoURL == "" || (spec.Source.Path == "" && spec.Source.Chart == "") { - conditions = append(conditions, argoappv1.ApplicationCondition{ - Type: argoappv1.ApplicationConditionInvalidSpecError, - Message: "spec.source.repoURL and either spec.source.path or spec.source.chart are required", - }) - return conditions, nil +func validateSourcePermissions(ctx context.Context, source argoappv1.ApplicationSource, proj *argoappv1.AppProject, project string, hasMultipleSources bool) []argoappv1.ApplicationCondition { + var conditions []argoappv1.ApplicationCondition + if hasMultipleSources { + if source.RepoURL == "" || (source.Path == "" && source.Chart == "" && source.Ref == "") { + conditions = append(conditions, argoappv1.ApplicationCondition{ + Type: argoappv1.ApplicationConditionInvalidSpecError, + Message: fmt.Sprintf("spec.source.repoURL and either source.path, source.chart, or source.ref are required for source %s", source), + }) + return conditions + } + } else { + if source.RepoURL == "" || (source.Path == "" && source.Chart == "") { + conditions = append(conditions, argoappv1.ApplicationCondition{ + Type: argoappv1.ApplicationConditionInvalidSpecError, + Message: "spec.source.repoURL and either spec.source.path or spec.source.chart are required", + }) + return conditions + } } - if spec.Source.Chart != "" && spec.Source.TargetRevision == "" { + if source.Chart != "" && source.TargetRevision == "" { conditions = append(conditions, argoappv1.ApplicationCondition{ Type: argoappv1.ApplicationConditionInvalidSpecError, Message: "spec.source.targetRevision is required if the manifest source is a helm chart", }) - return conditions, nil + return conditions } - if !proj.IsSourcePermitted(spec.Source) { - conditions = append(conditions, argoappv1.ApplicationCondition{ - Type: argoappv1.ApplicationConditionInvalidSpecError, - Message: fmt.Sprintf("application repo %s is not permitted in project '%s'", spec.Source.RepoURL, spec.Project), - }) + return conditions +} + +// ValidatePermissions ensures that the referenced cluster has been added to Argo CD and the app source repo and destination namespace/cluster are permitted in app project +func ValidatePermissions(ctx context.Context, spec *argoappv1.ApplicationSpec, proj *argoappv1.AppProject, db db.ArgoDB) ([]argoappv1.ApplicationCondition, error) { + conditions := make([]argoappv1.ApplicationCondition, 0) + + if spec.HasMultipleSources() { + for _, source := range spec.Sources { + condition := validateSourcePermissions(ctx, source, proj, spec.Project, spec.HasMultipleSources()) + if len(condition) > 0 { + conditions = append(conditions, condition...) + return conditions, nil + } + + if !proj.IsSourcePermitted(source) { + conditions = append(conditions, argoappv1.ApplicationCondition{ + Type: argoappv1.ApplicationConditionInvalidSpecError, + Message: fmt.Sprintf("application repo %s is not permitted in project '%s'", source.RepoURL, spec.Project), + }) + } + } + + } else { + conditions = validateSourcePermissions(ctx, spec.GetSource(), proj, spec.Project, spec.HasMultipleSources()) + if len(conditions) > 0 { + return conditions, nil + } + + if !proj.IsSourcePermitted(spec.GetSource()) { + conditions = append(conditions, argoappv1.ApplicationCondition{ + Type: argoappv1.ApplicationConditionInvalidSpecError, + Message: fmt.Sprintf("application repo %s is not permitted in project '%s'", spec.GetSource().RepoURL, spec.Project), + }) + } } // ValidateDestination will resolve the destination's server address from its name for us, if possible @@ -362,6 +495,7 @@ func ValidatePermissions(ctx context.Context, spec *argoappv1.ApplicationSpec, p } // Ensure the k8s cluster the app is referencing, is configured in Argo CD _, err = db.GetCluster(ctx, spec.Destination.Server) + if err != nil { if errStatus, ok := status.FromError(err); ok && errStatus.Code() == codes.NotFound { conditions = append(conditions, argoappv1.ApplicationCondition{ @@ -468,49 +602,95 @@ func GetAppProject(app *argoappv1.Application, projLister applicationsv1.AppProj } // verifyGenerateManifests verifies a repo path can generate manifests -func verifyGenerateManifests(ctx context.Context, repoRes *argoappv1.Repository, helmRepos argoappv1.Repositories, helmOptions *argoappv1.HelmOptions, app *argoappv1.Application, repoClient apiclient.RepoServerServiceClient, kustomizeOptions *argoappv1.KustomizeOptions, plugins []*argoappv1.ConfigManagementPlugin, kubeVersion string, apiVersions []string, repositoryCredentials []*argoappv1.RepoCreds, enableGenerateManifests map[string]bool, settingsMgr *settings.SettingsManager) []argoappv1.ApplicationCondition { - spec := &app.Spec +func verifyGenerateManifests( + ctx context.Context, + db db.ArgoDB, + helmRepos argoappv1.Repositories, + helmOptions *argoappv1.HelmOptions, + name string, + dest argoappv1.ApplicationDestination, + sources []argoappv1.ApplicationSource, + repoClient apiclient.RepoServerServiceClient, + plugins []*argoappv1.ConfigManagementPlugin, + kubeVersion string, + apiVersions []string, + repositoryCredentials []*argoappv1.RepoCreds, + enableGenerateManifests map[string]bool, + settingsMgr *settings.SettingsManager, + hasMultipleSources bool, + refSources argoappv1.RefTargetRevisionMapping, +) []argoappv1.ApplicationCondition { var conditions []argoappv1.ApplicationCondition - if spec.Destination.Server == "" { + if dest.Server == "" { conditions = append(conditions, argoappv1.ApplicationCondition{ Type: argoappv1.ApplicationConditionInvalidSpecError, Message: errDestinationMissing, }) } - - req := apiclient.ManifestRequest{ - Repo: &argoappv1.Repository{ - Repo: spec.Source.RepoURL, - Type: repoRes.Type, - Name: repoRes.Name, - Proxy: repoRes.Proxy, - }, - Repos: helmRepos, - Revision: spec.Source.TargetRevision, - AppName: app.Name, - Namespace: spec.Destination.Namespace, - ApplicationSource: &spec.Source, - Plugins: plugins, - KustomizeOptions: kustomizeOptions, - KubeVersion: kubeVersion, - ApiVersions: apiVersions, - HelmOptions: helmOptions, - HelmRepoCreds: repositoryCredentials, - TrackingMethod: string(GetTrackingMethod(settingsMgr)), - EnabledSourceTypes: enableGenerateManifests, - NoRevisionCache: true, - } - req.Repo.CopyCredentialsFromRepo(repoRes) - req.Repo.CopySettingsFrom(repoRes) - - // Only check whether we can access the application's path, - // and not whether it actually contains any manifests. - _, err := repoClient.GenerateManifest(ctx, &req) + // If source is Kustomize add build options + kustomizeSettings, err := settingsMgr.GetKustomizeSettings() if err != nil { conditions = append(conditions, argoappv1.ApplicationCondition{ Type: argoappv1.ApplicationConditionInvalidSpecError, - Message: fmt.Sprintf("Unable to generate manifests in %s: %v", spec.Source.Path, err), + Message: fmt.Sprintf("Error getting Kustomize settings: %v", err), }) + return conditions // Can't perform the next check without settings. + } + + for _, source := range sources { + repoRes, err := db.GetRepository(ctx, source.RepoURL) + if err != nil { + conditions = append(conditions, argoappv1.ApplicationCondition{ + Type: argoappv1.ApplicationConditionInvalidSpecError, + Message: fmt.Sprintf("Unable to get repository: %v", err), + }) + continue + } + kustomizeOptions, err := kustomizeSettings.GetOptions(source) + if err != nil { + conditions = append(conditions, argoappv1.ApplicationCondition{ + Type: argoappv1.ApplicationConditionInvalidSpecError, + Message: fmt.Sprintf("Error getting Kustomize options: %v", err), + }) + continue + } + req := apiclient.ManifestRequest{ + Repo: &argoappv1.Repository{ + Repo: source.RepoURL, + Type: repoRes.Type, + Name: repoRes.Name, + Proxy: repoRes.Proxy, + }, + Repos: helmRepos, + Revision: source.TargetRevision, + AppName: name, + Namespace: dest.Namespace, + ApplicationSource: &source, + Plugins: plugins, + KustomizeOptions: kustomizeOptions, + KubeVersion: kubeVersion, + ApiVersions: apiVersions, + HelmOptions: helmOptions, + HelmRepoCreds: repositoryCredentials, + TrackingMethod: string(GetTrackingMethod(settingsMgr)), + EnabledSourceTypes: enableGenerateManifests, + NoRevisionCache: true, + HasMultipleSources: hasMultipleSources, + RefSources: refSources, + } + req.Repo.CopyCredentialsFromRepo(repoRes) + req.Repo.CopySettingsFrom(repoRes) + + // Only check whether we can access the application's path, + // and not whether it actually contains any manifests. + _, err = repoClient.GenerateManifest(ctx, &req) + if err != nil { + errMessage := fmt.Sprintf("Unable to generate manifests in %s: %s", source.Path, err) + conditions = append(conditions, argoappv1.ApplicationCondition{ + Type: argoappv1.ApplicationConditionInvalidSpecError, + Message: errMessage, + }) + } } return conditions @@ -561,27 +741,38 @@ func NormalizeApplicationSpec(spec *argoappv1.ApplicationSpec) *argoappv1.Applic spec.Project = argoappv1.DefaultAppProjectName } + if spec.Sources != nil && len(spec.Sources) > 0 { + for _, source := range spec.Sources { + NormalizeSource(&source) + } + } else { + NormalizeSource(spec.Source) + } + return spec +} + +func NormalizeSource(source *argoappv1.ApplicationSource) *argoappv1.ApplicationSource { // 3. If any app sources are their zero values, then nil out the pointers to the source spec. // This makes it easier for users to switch between app source types if they are not using // any of the source-specific parameters. - if spec.Source.Kustomize != nil && spec.Source.Kustomize.IsZero() { - spec.Source.Kustomize = nil - } - if spec.Source.Helm != nil && spec.Source.Helm.IsZero() { - spec.Source.Helm = nil - } - if spec.Source.Directory != nil && spec.Source.Directory.IsZero() { - if spec.Source.Directory.Exclude != "" && spec.Source.Directory.Include != "" { - spec.Source.Directory = &argoappv1.ApplicationSourceDirectory{Exclude: spec.Source.Directory.Exclude, Include: spec.Source.Directory.Include} - } else if spec.Source.Directory.Exclude != "" { - spec.Source.Directory = &argoappv1.ApplicationSourceDirectory{Exclude: spec.Source.Directory.Exclude} - } else if spec.Source.Directory.Include != "" { - spec.Source.Directory = &argoappv1.ApplicationSourceDirectory{Include: spec.Source.Directory.Include} + if source.Kustomize != nil && source.Kustomize.IsZero() { + source.Kustomize = nil + } + if source.Helm != nil && source.Helm.IsZero() { + source.Helm = nil + } + if source.Directory != nil && source.Directory.IsZero() { + if source.Directory.Exclude != "" && source.Directory.Include != "" { + source.Directory = &argoappv1.ApplicationSourceDirectory{Exclude: source.Directory.Exclude, Include: source.Directory.Include} + } else if source.Directory.Exclude != "" { + source.Directory = &argoappv1.ApplicationSourceDirectory{Exclude: source.Directory.Exclude} + } else if source.Directory.Include != "" { + source.Directory = &argoappv1.ApplicationSourceDirectory{Include: source.Directory.Include} } else { - spec.Source.Directory = nil + source.Directory = nil } } - return spec + return source } func GetPermittedReposCredentials(proj *argoappv1.AppProject, repoCreds []*argoappv1.RepoCreds) ([]*argoappv1.RepoCreds, error) { diff --git a/util/argo/argo_test.go b/util/argo/argo_test.go index 9bf707d126c22..d44aa7f6134b7 100644 --- a/util/argo/argo_test.go +++ b/util/argo/argo_test.go @@ -2,6 +2,7 @@ package argo import ( "context" + "errors" "fmt" "path/filepath" "testing" @@ -109,34 +110,36 @@ func TestContainsSyncResource(t *testing.T) { func TestNilOutZerValueAppSources(t *testing.T) { var spec *argoappv1.ApplicationSpec { - spec = NormalizeApplicationSpec(&argoappv1.ApplicationSpec{Source: argoappv1.ApplicationSource{Kustomize: &argoappv1.ApplicationSourceKustomize{NamePrefix: "foo"}}}) - assert.NotNil(t, spec.Source.Kustomize) - spec = NormalizeApplicationSpec(&argoappv1.ApplicationSpec{Source: argoappv1.ApplicationSource{Kustomize: &argoappv1.ApplicationSourceKustomize{NamePrefix: ""}}}) - assert.Nil(t, spec.Source.Kustomize) + spec = NormalizeApplicationSpec(&argoappv1.ApplicationSpec{Source: &argoappv1.ApplicationSource{Kustomize: &argoappv1.ApplicationSourceKustomize{NamePrefix: "foo"}}}) + assert.NotNil(t, spec.GetSource().Kustomize) + spec = NormalizeApplicationSpec(&argoappv1.ApplicationSpec{Source: &argoappv1.ApplicationSource{Kustomize: &argoappv1.ApplicationSourceKustomize{NamePrefix: ""}}}) + source := spec.GetSource() + assert.Nil(t, source.Kustomize) } { - spec = NormalizeApplicationSpec(&argoappv1.ApplicationSpec{Source: argoappv1.ApplicationSource{Kustomize: &argoappv1.ApplicationSourceKustomize{NameSuffix: "foo"}}}) - assert.NotNil(t, spec.Source.Kustomize) - spec = NormalizeApplicationSpec(&argoappv1.ApplicationSpec{Source: argoappv1.ApplicationSource{Kustomize: &argoappv1.ApplicationSourceKustomize{NameSuffix: ""}}}) - assert.Nil(t, spec.Source.Kustomize) + spec = NormalizeApplicationSpec(&argoappv1.ApplicationSpec{Source: &argoappv1.ApplicationSource{Kustomize: &argoappv1.ApplicationSourceKustomize{NameSuffix: "foo"}}}) + assert.NotNil(t, spec.GetSource().Kustomize) + spec = NormalizeApplicationSpec(&argoappv1.ApplicationSpec{Source: &argoappv1.ApplicationSource{Kustomize: &argoappv1.ApplicationSourceKustomize{NameSuffix: ""}}}) + source := spec.GetSource() + assert.Nil(t, source.Kustomize) } { - spec = NormalizeApplicationSpec(&argoappv1.ApplicationSpec{Source: argoappv1.ApplicationSource{Helm: &argoappv1.ApplicationSourceHelm{ValueFiles: []string{"values.yaml"}}}}) - assert.NotNil(t, spec.Source.Helm) - spec = NormalizeApplicationSpec(&argoappv1.ApplicationSpec{Source: argoappv1.ApplicationSource{Helm: &argoappv1.ApplicationSourceHelm{ValueFiles: []string{}}}}) - assert.Nil(t, spec.Source.Helm) + spec = NormalizeApplicationSpec(&argoappv1.ApplicationSpec{Source: &argoappv1.ApplicationSource{Helm: &argoappv1.ApplicationSourceHelm{ValueFiles: []string{"values.yaml"}}}}) + assert.NotNil(t, spec.GetSource().Helm) + spec = NormalizeApplicationSpec(&argoappv1.ApplicationSpec{Source: &argoappv1.ApplicationSource{Helm: &argoappv1.ApplicationSourceHelm{ValueFiles: []string{}}}}) + assert.Nil(t, spec.GetSource().Helm) } { - spec = NormalizeApplicationSpec(&argoappv1.ApplicationSpec{Source: argoappv1.ApplicationSource{Directory: &argoappv1.ApplicationSourceDirectory{Recurse: true}}}) - assert.NotNil(t, spec.Source.Directory) - spec = NormalizeApplicationSpec(&argoappv1.ApplicationSpec{Source: argoappv1.ApplicationSource{Directory: &argoappv1.ApplicationSourceDirectory{Recurse: false}}}) - assert.Nil(t, spec.Source.Directory) + spec = NormalizeApplicationSpec(&argoappv1.ApplicationSpec{Source: &argoappv1.ApplicationSource{Directory: &argoappv1.ApplicationSourceDirectory{Recurse: true}}}) + assert.NotNil(t, spec.GetSource().Directory) + spec = NormalizeApplicationSpec(&argoappv1.ApplicationSpec{Source: &argoappv1.ApplicationSource{Directory: &argoappv1.ApplicationSourceDirectory{Recurse: false}}}) + assert.Nil(t, spec.GetSource().Directory) } } func TestValidatePermissionsEmptyDestination(t *testing.T) { conditions, err := ValidatePermissions(context.Background(), &argoappv1.ApplicationSpec{ - Source: argoappv1.ApplicationSource{RepoURL: "https://github.com/argoproj/argo-cd", Path: "."}, + Source: &argoappv1.ApplicationSource{RepoURL: "https://github.com/argoproj/argo-cd", Path: "."}, }, &argoappv1.AppProject{ Spec: argoappv1.AppProjectSpec{ SourceRepos: []string{"*"}, @@ -148,17 +151,23 @@ func TestValidatePermissionsEmptyDestination(t *testing.T) { } func TestValidateChartWithoutRevision(t *testing.T) { - conditions, err := ValidatePermissions(context.Background(), &argoappv1.ApplicationSpec{ - Source: argoappv1.ApplicationSource{RepoURL: "https://charts.helm.sh/incubator/", Chart: "myChart", TargetRevision: ""}, + appSpec := &argoappv1.ApplicationSpec{ + Source: &argoappv1.ApplicationSource{RepoURL: "https://charts.helm.sh/incubator/", Chart: "myChart", TargetRevision: ""}, Destination: argoappv1.ApplicationDestination{ Server: "https://kubernetes.default.svc", Namespace: "default", }, - }, &argoappv1.AppProject{ + } + cluster := &argoappv1.Cluster{Server: "https://kubernetes.default.svc"} + db := &dbmocks.ArgoDB{} + ctx := context.Background() + db.On("GetCluster", ctx, appSpec.Destination.Server).Return(cluster, nil) + + conditions, err := ValidatePermissions(ctx, appSpec, &argoappv1.AppProject{ Spec: argoappv1.AppProjectSpec{ SourceRepos: []string{"*"}, Destinations: []argoappv1.ApplicationDestination{{Server: "*", Namespace: "*"}}, }, - }, nil) + }, db) assert.NoError(t, err) assert.Equal(t, 1, len(conditions)) assert.Equal(t, argoappv1.ApplicationConditionInvalidSpecError, conditions[0].Type) @@ -195,12 +204,12 @@ func TestValidateRepo(t *testing.T) { GroupKind: schema.GroupKind{Kind: "Deployment"}, }} kubeVersion := "v1.16" - kustomizeOptions := &argoappv1.KustomizeOptions{BuildOptions: "sample options"} + kustomizeOptions := &argoappv1.KustomizeOptions{BuildOptions: ""} repo := &argoappv1.Repository{Repo: fmt.Sprintf("file://%s", repoPath)} cluster := &argoappv1.Cluster{Server: "sample server"} app := &argoappv1.Application{ Spec: argoappv1.ApplicationSpec{ - Source: argoappv1.ApplicationSource{ + Source: &argoappv1.ApplicationSource{ RepoURL: repo.Repo, }, Destination: argoappv1.ApplicationDestination{ @@ -219,9 +228,10 @@ func TestValidateRepo(t *testing.T) { helmRepos := []*argoappv1.Repository{{Repo: "sample helm repo"}} repoClient := &mocks.RepoServerServiceClient{} + source := app.Spec.GetSource() repoClient.On("GetAppDetails", context.Background(), &apiclient.RepoServerAppDetailsQuery{ Repo: repo, - Source: &app.Spec.Source, + Source: &source, Repos: helmRepos, KustomizeOptions: kustomizeOptions, HelmOptions: &argoappv1.HelmOptions{ValuesFileSchemes: []string{"https", "http"}}, @@ -278,14 +288,14 @@ func TestValidateRepo(t *testing.T) { kubeClient := fake.NewSimpleClientset(&cm) settingsMgr := settings.NewSettingsManager(context.Background(), kubeClient, test.FakeArgoCDNamespace) - conditions, err := ValidateRepo(context.Background(), app, repoClientSet, db, kustomizeOptions, nil, &kubetest.MockKubectlCmd{Version: kubeVersion, APIResources: apiResources}, proj, settingsMgr) + conditions, err := ValidateRepo(context.Background(), app, repoClientSet, db, nil, &kubetest.MockKubectlCmd{Version: kubeVersion, APIResources: apiResources}, proj, settingsMgr) assert.NoError(t, err) assert.Empty(t, conditions) assert.ElementsMatch(t, []string{"apps/v1beta1", "apps/v1beta1/Deployment", "apps/v1beta2", "apps/v1beta2/Deployment"}, receivedRequest.ApiVersions) assert.Equal(t, kubeVersion, receivedRequest.KubeVersion) assert.Equal(t, app.Spec.Destination.Namespace, receivedRequest.Namespace) - assert.Equal(t, &app.Spec.Source, receivedRequest.ApplicationSource) + assert.Equal(t, &source, receivedRequest.ApplicationSource) assert.Equal(t, kustomizeOptions, receivedRequest.KustomizeOptions) } @@ -358,14 +368,14 @@ func TestFilterByRepo(t *testing.T) { apps := []argoappv1.Application{ { Spec: argoappv1.ApplicationSpec{ - Source: argoappv1.ApplicationSource{ + Source: &argoappv1.ApplicationSource{ RepoURL: "git@github.com:owner/repo.git", }, }, }, { Spec: argoappv1.ApplicationSpec{ - Source: argoappv1.ApplicationSource{ + Source: &argoappv1.ApplicationSource{ RepoURL: "git@github.com:owner/otherrepo.git", }, }, @@ -391,7 +401,7 @@ func TestFilterByRepo(t *testing.T) { func TestValidatePermissions(t *testing.T) { t.Run("Empty Repo URL result in condition", func(t *testing.T) { spec := argoappv1.ApplicationSpec{ - Source: argoappv1.ApplicationSource{ + Source: &argoappv1.ApplicationSource{ RepoURL: "", }, } @@ -406,7 +416,7 @@ func TestValidatePermissions(t *testing.T) { t.Run("Incomplete Path/Chart combo result in condition", func(t *testing.T) { spec := argoappv1.ApplicationSpec{ - Source: argoappv1.ApplicationSource{ + Source: &argoappv1.ApplicationSource{ RepoURL: "http://some/where", Path: "", Chart: "", @@ -423,7 +433,7 @@ func TestValidatePermissions(t *testing.T) { t.Run("Helm chart requires targetRevision", func(t *testing.T) { spec := argoappv1.ApplicationSpec{ - Source: argoappv1.ApplicationSource{ + Source: &argoappv1.ApplicationSource{ RepoURL: "http://some/where", Path: "", Chart: "somechart", @@ -440,7 +450,7 @@ func TestValidatePermissions(t *testing.T) { t.Run("Application source is not permitted in project", func(t *testing.T) { spec := argoappv1.ApplicationSpec{ - Source: argoappv1.ApplicationSource{ + Source: &argoappv1.ApplicationSource{ RepoURL: "http://some/where", Path: "", Chart: "somechart", @@ -473,7 +483,7 @@ func TestValidatePermissions(t *testing.T) { t.Run("Application destination is not permitted in project", func(t *testing.T) { spec := argoappv1.ApplicationSpec{ - Source: argoappv1.ApplicationSource{ + Source: &argoappv1.ApplicationSource{ RepoURL: "http://some/where", Path: "", Chart: "somechart", @@ -506,7 +516,7 @@ func TestValidatePermissions(t *testing.T) { t.Run("Destination cluster does not exist", func(t *testing.T) { spec := argoappv1.ApplicationSpec{ - Source: argoappv1.ApplicationSource{ + Source: &argoappv1.ApplicationSource{ RepoURL: "http://some/where", Path: "", Chart: "somechart", @@ -538,7 +548,7 @@ func TestValidatePermissions(t *testing.T) { t.Run("Destination cluster name does not exist", func(t *testing.T) { spec := argoappv1.ApplicationSpec{ - Source: argoappv1.ApplicationSource{ + Source: &argoappv1.ApplicationSource{ RepoURL: "http://some/where", Path: "", Chart: "somechart", @@ -570,7 +580,7 @@ func TestValidatePermissions(t *testing.T) { t.Run("Cannot get cluster info from DB", func(t *testing.T) { spec := argoappv1.ApplicationSpec{ - Source: argoappv1.ApplicationSource{ + Source: &argoappv1.ApplicationSource{ RepoURL: "http://some/where", Path: "", Chart: "somechart", @@ -600,7 +610,7 @@ func TestValidatePermissions(t *testing.T) { t.Run("Destination cluster name resolves to valid server", func(t *testing.T) { spec := argoappv1.ApplicationSpec{ - Source: argoappv1.ApplicationSource{ + Source: &argoappv1.ApplicationSource{ RepoURL: "http://some/where", Path: "", Chart: "somechart", @@ -1014,5 +1024,184 @@ func Test_AppInstanceNameFromQualified(t *testing.T) { assert.Equal(t, tt.result, result) }) } +} + +func Test_GetRefSources(t *testing.T) { + repoPath, err := filepath.Abs("./../..") + assert.NoError(t, err) + + getMultiSourceAppSpec := func(sources argoappv1.ApplicationSources) *argoappv1.ApplicationSpec { + return &argoappv1.ApplicationSpec{ + Sources: sources, + } + } + + repo := &argoappv1.Repository{Repo: fmt.Sprintf("file://%s", repoPath)} + + t.Run("target ref exists", func(t *testing.T) { + repoDB := &dbmocks.ArgoDB{} + repoDB.On("GetRepository", context.Background(), repo.Repo).Return(repo, nil) + + argoSpec := getMultiSourceAppSpec(argoappv1.ApplicationSources{ + {RepoURL: fmt.Sprintf("file://%s", repoPath), Ref: "source1"}, + {RepoURL: fmt.Sprintf("file://%s", repoPath)}, + }) + + refSources, err := GetRefSources(context.TODO(), *argoSpec, repoDB) + + expectedRefSource := argoappv1.RefTargetRevisionMapping{ + "$source1": &argoappv1.RefTarget{ + Repo: *repo, + }, + } + assert.NoError(t, err) + assert.Len(t, refSources, 1) + assert.Equal(t, expectedRefSource, refSources) + }) + + t.Run("target ref does not exist", func(t *testing.T) { + repoDB := &dbmocks.ArgoDB{} + repoDB.On("GetRepository", context.Background(), "file://does-not-exist").Return(nil, errors.New("repo does not exist")) + + argoSpec := getMultiSourceAppSpec(argoappv1.ApplicationSources{ + {RepoURL: "file://does-not-exist", Ref: "source1"}, + }) + + refSources, err := GetRefSources(context.TODO(), *argoSpec, repoDB) + + assert.Error(t, err) + assert.Empty(t, refSources) + }) + + t.Run("invalid ref", func(t *testing.T) { + argoSpec := getMultiSourceAppSpec(argoappv1.ApplicationSources{ + {RepoURL: "file://does-not-exist", Ref: "%invalid-name%"}, + }) + + refSources, err := GetRefSources(context.TODO(), *argoSpec, &dbmocks.ArgoDB{}) + + assert.Error(t, err) + assert.Empty(t, refSources) + }) + + t.Run("duplicate ref keys", func(t *testing.T) { + argoSpec := getMultiSourceAppSpec(argoappv1.ApplicationSources{ + {RepoURL: "file://does-not-exist", Ref: "source1"}, + {RepoURL: "file://does-not-exist", Ref: "source1"}, + }) + + refSources, err := GetRefSources(context.TODO(), *argoSpec, &dbmocks.ArgoDB{}) + + assert.Error(t, err) + assert.Empty(t, refSources) + }) +} + +func TestValidatePermissionsMultipleSources(t *testing.T) { + + t.Run("Empty Repo URL result in condition", func(t *testing.T) { + spec := argoappv1.ApplicationSpec{ + Sources: argoappv1.ApplicationSources{ + {RepoURL: ""}, + }, + } + + proj := argoappv1.AppProject{} + db := &dbmocks.ArgoDB{} + conditions, err := ValidatePermissions(context.Background(), &spec, &proj, db) + assert.NoError(t, err) + assert.Len(t, conditions, 1) + assert.Equal(t, argoappv1.ApplicationConditionInvalidSpecError, conditions[0].Type) + assert.Contains(t, conditions[0].Message, "are required") + }) + + t.Run("Incomplete Path/Chart/Ref combo result in condition", func(t *testing.T) { + spec := argoappv1.ApplicationSpec{ + Sources: argoappv1.ApplicationSources{{ + RepoURL: "http://some/where", + Path: "", + Chart: "", + Ref: "", + }, + }, + } + proj := argoappv1.AppProject{} + db := &dbmocks.ArgoDB{} + conditions, err := ValidatePermissions(context.Background(), &spec, &proj, db) + assert.NoError(t, err) + assert.Len(t, conditions, 1) + assert.Equal(t, argoappv1.ApplicationConditionInvalidSpecError, conditions[0].Type) + assert.Contains(t, conditions[0].Message, "are required") + }) + + t.Run("One of the Application sources is not permitted in project", func(t *testing.T) { + spec := argoappv1.ApplicationSpec{ + Sources: argoappv1.ApplicationSources{{ + RepoURL: "http://some/where", + Path: "", + Chart: "somechart", + TargetRevision: "1.4.1", + }, + }, + Destination: argoappv1.ApplicationDestination{ + Server: "https://127.0.0.1:6443", + Namespace: "testns", + }, + } + proj := argoappv1.AppProject{ + Spec: argoappv1.AppProjectSpec{ + Destinations: []argoappv1.ApplicationDestination{ + { + Server: "*", + Namespace: "*", + }, + }, + SourceRepos: []string{"http://some/where/else"}, + }, + } + cluster := &argoappv1.Cluster{Server: "https://127.0.0.1:6443"} + db := &dbmocks.ArgoDB{} + db.On("GetCluster", context.Background(), spec.Destination.Server).Return(cluster, nil) + conditions, err := ValidatePermissions(context.Background(), &spec, &proj, db) + assert.NoError(t, err) + assert.Len(t, conditions, 1) + assert.Contains(t, conditions[0].Message, "application repo http://some/where is not permitted") + }) + t.Run("Source with a Ref field and missing Path/Chart field", func(t *testing.T) { + spec := argoappv1.ApplicationSpec{ + Sources: argoappv1.ApplicationSources{{ + RepoURL: "http://some/where", + Path: "", + Chart: "", + Ref: "somechart", + }, + }, + Destination: argoappv1.ApplicationDestination{ + Name: "does-exist", + Namespace: "default", + }, + } + proj := argoappv1.AppProject{ + Spec: argoappv1.AppProjectSpec{ + Destinations: []argoappv1.ApplicationDestination{ + { + Server: "*", + Namespace: "default", + }, + }, + SourceRepos: []string{"http://some/where"}, + }, + } + db := &dbmocks.ArgoDB{} + cluster := argoappv1.Cluster{ + Name: "does-exist", + Server: "https://127.0.0.1:6443", + } + db.On("GetClusterServersByName", context.Background(), "does-exist").Return([]string{"https://127.0.0.1:6443"}, nil) + db.On("GetCluster", context.Background(), "https://127.0.0.1:6443").Return(&cluster, nil) + conditions, err := ValidatePermissions(context.Background(), &spec, &proj, db) + assert.NoError(t, err) + assert.Len(t, conditions, 0) + }) } diff --git a/util/helm/client.go b/util/helm/client.go index ec0c0bea4dbaa..566df0df61f51 100644 --- a/util/helm/client.go +++ b/util/helm/client.go @@ -65,7 +65,7 @@ func WithIndexCache(indexCache indexCache) ClientOpts { } } -func WithChartPaths(chartPaths *argoio.TempPaths) ClientOpts { +func WithChartPaths(chartPaths argoio.TempPaths) ClientOpts { return func(c *nativeHelmChart) { c.chartCachePaths = chartPaths } @@ -82,7 +82,7 @@ func NewClientWithLock(repoURL string, creds Creds, repoLock sync.KeyLock, enabl repoLock: repoLock, enableOci: enableOci, proxy: proxy, - chartCachePaths: argoio.NewTempPaths(os.TempDir()), + chartCachePaths: argoio.NewRandomizedTempPaths(os.TempDir()), } for i := range opts { opts[i](c) @@ -93,7 +93,7 @@ func NewClientWithLock(repoURL string, creds Creds, repoLock sync.KeyLock, enabl var _ Client = &nativeHelmChart{} type nativeHelmChart struct { - chartCachePaths *argoio.TempPaths + chartCachePaths argoio.TempPaths repoURL string creds Creds repoLock sync.KeyLock diff --git a/util/io/mocks/TempPaths.go b/util/io/mocks/TempPaths.go new file mode 100644 index 0000000000000..c4f293205907c --- /dev/null +++ b/util/io/mocks/TempPaths.go @@ -0,0 +1,65 @@ +// Code generated by mockery v2.13.1. DO NOT EDIT. + +package iomocks + +import mock "github.com/stretchr/testify/mock" + +// TempPaths is an autogenerated mock type for the TempPaths type +type TempPaths struct { + mock.Mock +} + +// Add provides a mock function with given fields: key, value +func (_m *TempPaths) Add(key string, value string) { + _m.Called(key, value) +} + +// GetPath provides a mock function with given fields: key +func (_m *TempPaths) GetPath(key string) (string, error) { + ret := _m.Called(key) + + var r0 string + if rf, ok := ret.Get(0).(func(string) string); ok { + r0 = rf(key) + } else { + r0 = ret.Get(0).(string) + } + + var r1 error + if rf, ok := ret.Get(1).(func(string) error); ok { + r1 = rf(key) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetPathIfExists provides a mock function with given fields: key +func (_m *TempPaths) GetPathIfExists(key string) string { + ret := _m.Called(key) + + var r0 string + if rf, ok := ret.Get(0).(func(string) string); ok { + r0 = rf(key) + } else { + r0 = ret.Get(0).(string) + } + + return r0 +} + +type mockConstructorTestingTNewTempPaths interface { + mock.TestingT + Cleanup(func()) +} + +// NewTempPaths creates a new instance of TempPaths. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +func NewTempPaths(t mockConstructorTestingTNewTempPaths) *TempPaths { + mock := &TempPaths{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/util/io/paths.go b/util/io/paths.go index b9c20283bcdcd..525dcda6c39ff 100644 --- a/util/io/paths.go +++ b/util/io/paths.go @@ -7,28 +7,34 @@ import ( "github.com/google/uuid" ) -// TempPaths allows generating and memoizing random paths, each path being mapped to a specific key. -type TempPaths struct { +type TempPaths interface { + Add(key string, value string) + GetPath(key string) (string, error) + GetPathIfExists(key string) string +} + +// RandomizedTempPaths allows generating and memoizing random paths, each path being mapped to a specific key. +type RandomizedTempPaths struct { root string paths map[string]string lock sync.Mutex } -func NewTempPaths(root string) *TempPaths { - return &TempPaths{ +func NewRandomizedTempPaths(root string) *RandomizedTempPaths { + return &RandomizedTempPaths{ root: root, paths: map[string]string{}, } } -func (p *TempPaths) Add(key string, value string) { +func (p *RandomizedTempPaths) Add(key string, value string) { p.lock.Lock() defer p.lock.Unlock() p.paths[key] = value } // GetPath generates a path for the given key or returns previously generated one. -func (p *TempPaths) GetPath(key string) (string, error) { +func (p *RandomizedTempPaths) GetPath(key string) (string, error) { p.lock.Lock() defer p.lock.Unlock() if val, ok := p.paths[key]; ok { @@ -42,3 +48,13 @@ func (p *TempPaths) GetPath(key string) (string, error) { p.paths[key] = repoPath return repoPath, nil } + +// GetPathIfExists gets a path for the given key if it exists. Otherwise, returns an empty string. +func (p *RandomizedTempPaths) GetPathIfExists(key string) string { + p.lock.Lock() + defer p.lock.Unlock() + if val, ok := p.paths[key]; ok { + return val + } + return "" +} diff --git a/util/io/paths_test.go b/util/io/paths_test.go index ea98dbaafb878..950e99fc020ec 100644 --- a/util/io/paths_test.go +++ b/util/io/paths_test.go @@ -9,7 +9,7 @@ import ( ) func TestGetPath_SameURLs(t *testing.T) { - paths := NewTempPaths(os.TempDir()) + paths := NewRandomizedTempPaths(os.TempDir()) res1, err := paths.GetPath("https://localhost/test.txt") require.NoError(t, err) res2, err := paths.GetPath("https://localhost/test.txt") @@ -18,7 +18,7 @@ func TestGetPath_SameURLs(t *testing.T) { } func TestGetPath_DifferentURLs(t *testing.T) { - paths := NewTempPaths(os.TempDir()) + paths := NewRandomizedTempPaths(os.TempDir()) res1, err := paths.GetPath("https://localhost/test1.txt") require.NoError(t, err) res2, err := paths.GetPath("https://localhost/test2.txt") @@ -27,11 +27,25 @@ func TestGetPath_DifferentURLs(t *testing.T) { } func TestGetPath_SameURLsDifferentInstances(t *testing.T) { - paths1 := NewTempPaths(os.TempDir()) + paths1 := NewRandomizedTempPaths(os.TempDir()) res1, err := paths1.GetPath("https://localhost/test.txt") require.NoError(t, err) - paths2 := NewTempPaths(os.TempDir()) + paths2 := NewRandomizedTempPaths(os.TempDir()) res2, err := paths2.GetPath("https://localhost/test.txt") require.NoError(t, err) assert.NotEqual(t, res1, res2) } + +func TestGetPathIfExists(t *testing.T) { + paths := NewRandomizedTempPaths(os.TempDir()) + t.Run("does not exist", func(t *testing.T) { + path := paths.GetPathIfExists("https://localhost/test.txt") + assert.Empty(t, path) + }) + t.Run("does exist", func(t *testing.T) { + _, err := paths.GetPath("https://localhost/test.txt") + require.NoError(t, err) + path := paths.GetPathIfExists("https://localhost/test.txt") + assert.NotEmpty(t, path) + }) +} diff --git a/util/notification/expression/repo/repo.go b/util/notification/expression/repo/repo.go index df2ff5bcc5796..060060cbccd68 100644 --- a/util/notification/expression/repo/repo.go +++ b/util/notification/expression/repo/repo.go @@ -32,7 +32,7 @@ func getApplicationSource(obj *unstructured.Unstructured) (*v1alpha1.Application if err != nil { return nil, err } - return &application.Spec.Source, nil + return application.Spec.GetSourcePtr(), nil } func getAppDetails(app *unstructured.Unstructured, argocdService service.Service) (*shared.AppDetail, error) { diff --git a/util/webhook/webhook.go b/util/webhook/webhook.go index 75be937382b75..6eef36ac7886e 100644 --- a/util/webhook/webhook.go +++ b/util/webhook/webhook.go @@ -237,16 +237,20 @@ func (a *ArgoCDWebhookHandler) HandleEvent(payload interface{}) { continue } for _, app := range apps.Items { - if appRevisionHasChanged(&app, revision, touchedHead) && appUsesURL(&app, webURL, repoRegexp) { - if appFilesHaveChanged(&app, changedFiles) { - _, err = argo.RefreshApp(appIf, app.ObjectMeta.Name, v1alpha1.RefreshTypeNormal) - if err != nil { - log.Warnf("Failed to refresh app '%s' for controller reprocessing: %v", app.ObjectMeta.Name, err) - continue - } - } else if change.shaBefore != "" && change.shaAfter != "" { - if err := a.storePreviouslyCachedManifests(&app, change, trackingMethod, appInstanceLabelKey); err != nil { - log.Warnf("Failed to store cached manifests of previous revision for app '%s': %v", app.Name, err) + for _, source := range app.Spec.GetSources() { + if sourceRevisionHasChanged(source, revision, touchedHead) && sourceUsesURL(source, webURL, repoRegexp) { + if appFilesHaveChanged(&app, changedFiles) { + _, err = argo.RefreshApp(appIf, app.ObjectMeta.Name, v1alpha1.RefreshTypeNormal) + if err != nil { + log.Warnf("Failed to refresh app '%s' for controller reprocessing: %v", app.ObjectMeta.Name, err) + continue + } + // No need to refresh multiple times if multiple sources match. + break + } else if change.shaBefore != "" && change.shaAfter != "" { + if err := a.storePreviouslyCachedManifests(&app, change, trackingMethod, appInstanceLabelKey); err != nil { + log.Warnf("Failed to store cached manifests of previous revision for app '%s': %v", app.Name, err) + } } } } @@ -285,17 +289,22 @@ func (a *ArgoCDWebhookHandler) storePreviouslyCachedManifests(app *v1alpha1.Appl return fmt.Errorf("error getting cluster info: %w", err) } - cache.LogDebugManifestCacheKeyFields("getting manifests cache", "webhook app revision changed", change.shaBefore, &app.Spec.Source, &clusterInfo, app.Spec.Destination.Namespace, trackingMethod, appInstanceLabelKey, app.Name) + refSources, err := argo.GetRefSources(context.Background(), app.Spec, a.db) + if err != nil { + return fmt.Errorf("error getting ref sources: %w", err) + } + source := app.Spec.GetSource() + cache.LogDebugManifestCacheKeyFields("getting manifests cache", "webhook app revision changed", change.shaBefore, &source, refSources, &clusterInfo, app.Spec.Destination.Namespace, trackingMethod, appInstanceLabelKey, app.Name) var cachedManifests cache.CachedManifestResponse - if err := a.repoCache.GetManifests(change.shaBefore, &app.Spec.Source, &clusterInfo, app.Spec.Destination.Namespace, trackingMethod, appInstanceLabelKey, app.Name, &cachedManifests); err != nil { - return fmt.Errorf("error getting manifests: %w", err) + if err := a.repoCache.GetManifests(change.shaBefore, &source, refSources, &clusterInfo, app.Spec.Destination.Namespace, trackingMethod, appInstanceLabelKey, app.Name, &cachedManifests); err != nil { + return err } - cache.LogDebugManifestCacheKeyFields("setting manifests cache", "webhook app revision changed", change.shaAfter, &app.Spec.Source, &clusterInfo, app.Spec.Destination.Namespace, trackingMethod, appInstanceLabelKey, app.Name) + cache.LogDebugManifestCacheKeyFields("setting manifests cache", "webhook app revision changed", change.shaAfter, &source, refSources, &clusterInfo, app.Spec.Destination.Namespace, trackingMethod, appInstanceLabelKey, app.Name) - if err = a.repoCache.SetManifests(change.shaAfter, &app.Spec.Source, &clusterInfo, app.Spec.Destination.Namespace, trackingMethod, appInstanceLabelKey, app.Name, &cachedManifests); err != nil { - return fmt.Errorf("error setting manifests: %w", err) + if err = a.repoCache.SetManifests(change.shaAfter, &source, refSources, &clusterInfo, app.Spec.Destination.Namespace, trackingMethod, appInstanceLabelKey, app.Name, &cachedManifests); err != nil { + return err } return nil } @@ -308,11 +317,12 @@ func getAppRefreshPaths(app *v1alpha1.Application) []string { continue } if filepath.IsAbs(item) { - item = item[1:] + paths = append(paths, item[1:]) } else { - item = filepath.Clean(filepath.Join(app.Spec.Source.Path, item)) + for _, source := range app.Spec.GetSources() { + paths = append(paths, filepath.Clean(filepath.Join(source.Path, item))) + } } - paths = append(paths, item) } } return paths @@ -363,28 +373,28 @@ func ensureAbsPath(input string) string { return input } -func appRevisionHasChanged(app *v1alpha1.Application, revision string, touchedHead bool) bool { - targetRev := parseRevision(app.Spec.Source.TargetRevision) +func sourceRevisionHasChanged(source v1alpha1.ApplicationSource, revision string, touchedHead bool) bool { + targetRev := parseRevision(source.TargetRevision) if targetRev == "HEAD" || targetRev == "" { // revision is head return touchedHead } targetRevisionHasPrefixList := []string{"refs/heads/", "refs/tags/"} for _, prefix := range targetRevisionHasPrefixList { - if strings.HasPrefix(app.Spec.Source.TargetRevision, prefix) { + if strings.HasPrefix(source.TargetRevision, prefix) { return revision == targetRev } } - return app.Spec.Source.TargetRevision == revision + return source.TargetRevision == revision } -func appUsesURL(app *v1alpha1.Application, webURL string, repoRegexp *regexp.Regexp) bool { - if !repoRegexp.MatchString(app.Spec.Source.RepoURL) { - log.Debugf("%s does not match %s", app.Spec.Source.RepoURL, repoRegexp.String()) +func sourceUsesURL(source v1alpha1.ApplicationSource, webURL string, repoRegexp *regexp.Regexp) bool { + if !repoRegexp.MatchString(source.RepoURL) { + log.Debugf("%s does not match %s", source.RepoURL, repoRegexp.String()) return false } - log.Debugf("%s uses repoURL %s", app.Spec.Source.RepoURL, webURL) + log.Debugf("%s uses repoURL %s", source.RepoURL, webURL) return true } diff --git a/util/webhook/webhook_test.go b/util/webhook/webhook_test.go index d81d00729deb5..203ad80a257c4 100644 --- a/util/webhook/webhook_test.go +++ b/util/webhook/webhook_test.go @@ -16,6 +16,8 @@ import ( bitbucketserver "gopkg.in/go-playground/webhooks.v5/bitbucket-server" "gopkg.in/go-playground/webhooks.v5/github" "gopkg.in/go-playground/webhooks.v5/gitlab" + "k8s.io/apimachinery/pkg/runtime" + kubetesting "k8s.io/client-go/testing" "github.com/argoproj/argo-cd/v2/util/cache/appstate" @@ -45,8 +47,22 @@ func (f fakeSettingsSrc) GetTrackingMethod() (string, error) { return "", nil } -func NewMockHandler() *ArgoCDWebhookHandler { - appClientset := appclientset.NewSimpleClientset() +type reactorDef struct { + verb string + resource string + reaction kubetesting.ReactionFunc +} + +func NewMockHandler(reactor *reactorDef, objects ...runtime.Object) *ArgoCDWebhookHandler { + appClientset := appclientset.NewSimpleClientset(objects...) + if reactor != nil { + defaultReactor := appClientset.ReactionChain[0] + appClientset.ReactionChain = nil + appClientset.AddReactor("list", "*", func(action kubetesting.Action) (handled bool, ret runtime.Object, err error) { + return defaultReactor.React(action) + }) + appClientset.AddReactor(reactor.verb, reactor.resource, reactor.reaction) + } cacheClient := cacheutil.NewCache(cacheutil.NewInMemoryCache(1 * time.Hour)) return NewHandler("", appClientset, &settings.ArgoCDSettings{}, &fakeSettingsSrc{}, cache.NewCache( cacheClient, @@ -57,7 +73,7 @@ func NewMockHandler() *ArgoCDWebhookHandler { func TestGitHubCommitEvent(t *testing.T) { hook := test.NewGlobal() - h := NewMockHandler() + h := NewMockHandler(nil) req := httptest.NewRequest("POST", "/api/webhook", nil) req.Header.Set("X-GitHub-Event", "push") eventJSON, err := os.ReadFile("testdata/github-commit-event.json") @@ -71,9 +87,63 @@ func TestGitHubCommitEvent(t *testing.T) { hook.Reset() } +// TestGitHubCommitEvent_MultiSource_Refresh makes sure that a webhook will refresh a multi-source app when at least +// one source matches. +func TestGitHubCommitEvent_MultiSource_Refresh(t *testing.T) { + hook := test.NewGlobal() + var patched bool + reaction := func(action kubetesting.Action) (handled bool, ret runtime.Object, err error) { + patchAction := action.(kubetesting.PatchAction) + assert.Equal(t, "app-to-refresh", patchAction.GetName()) + patched = true + return true, nil, nil + } + h := NewMockHandler(&reactorDef{"patch", "applications", reaction}, &v1alpha1.Application{ + ObjectMeta: metav1.ObjectMeta{ + Name: "app-to-refresh", + }, + Spec: v1alpha1.ApplicationSpec{ + Sources: v1alpha1.ApplicationSources{ + { + RepoURL: "https://github.com/some/unrelated-repo", + Path: ".", + }, + { + RepoURL: "https://github.com/jessesuen/test-repo", + Path: ".", + }, + }, + }, + }, &v1alpha1.Application{ + ObjectMeta: metav1.ObjectMeta{ + Name: "app-to-ignore", + }, + Spec: v1alpha1.ApplicationSpec{ + Sources: v1alpha1.ApplicationSources{ + { + RepoURL: "https://github.com/some/unrelated-repo", + Path: ".", + }, + }, + }, + }) + req := httptest.NewRequest("POST", "/api/webhook", nil) + req.Header.Set("X-GitHub-Event", "push") + eventJSON, err := os.ReadFile("testdata/github-commit-event.json") + assert.NoError(t, err) + req.Body = io.NopCloser(bytes.NewReader(eventJSON)) + w := httptest.NewRecorder() + h.Handler(w, req) + assert.Equal(t, w.Code, http.StatusOK) + expectedLogResult := "Requested app 'app-to-refresh' refresh" + assert.Equal(t, expectedLogResult, hook.LastEntry().Message) + assert.True(t, patched) + hook.Reset() +} + func TestGitHubTagEvent(t *testing.T) { hook := test.NewGlobal() - h := NewMockHandler() + h := NewMockHandler(nil) req := httptest.NewRequest("POST", "/api/webhook", nil) req.Header.Set("X-GitHub-Event", "push") eventJSON, err := os.ReadFile("testdata/github-tag-event.json") @@ -89,7 +159,7 @@ func TestGitHubTagEvent(t *testing.T) { func TestGitHubPingEvent(t *testing.T) { hook := test.NewGlobal() - h := NewMockHandler() + h := NewMockHandler(nil) req := httptest.NewRequest("POST", "/api/webhook", nil) req.Header.Set("X-GitHub-Event", "ping") eventJSON, err := os.ReadFile("testdata/github-ping-event.json") @@ -105,7 +175,7 @@ func TestGitHubPingEvent(t *testing.T) { func TestBitbucketServerRepositoryReferenceChangedEvent(t *testing.T) { hook := test.NewGlobal() - h := NewMockHandler() + h := NewMockHandler(nil) req := httptest.NewRequest("POST", "/api/webhook", nil) req.Header.Set("X-Event-Key", "repo:refs_changed") eventJSON, err := os.ReadFile("testdata/bitbucket-server-event.json") @@ -123,7 +193,7 @@ func TestBitbucketServerRepositoryReferenceChangedEvent(t *testing.T) { func TestBitbucketServerRepositoryDiagnosticPingEvent(t *testing.T) { hook := test.NewGlobal() - h := NewMockHandler() + h := NewMockHandler(nil) eventJSON := "{\"test\": true}" req := httptest.NewRequest("POST", "/api/webhook", bytes.NewBufferString(eventJSON)) req.Header.Set("X-Event-Key", "diagnostics:ping") @@ -137,7 +207,7 @@ func TestBitbucketServerRepositoryDiagnosticPingEvent(t *testing.T) { func TestGogsPushEvent(t *testing.T) { hook := test.NewGlobal() - h := NewMockHandler() + h := NewMockHandler(nil) req := httptest.NewRequest("POST", "/api/webhook", nil) req.Header.Set("X-Gogs-Event", "push") eventJSON, err := os.ReadFile("testdata/gogs-event.json") @@ -153,7 +223,7 @@ func TestGogsPushEvent(t *testing.T) { func TestGitLabPushEvent(t *testing.T) { hook := test.NewGlobal() - h := NewMockHandler() + h := NewMockHandler(nil) req := httptest.NewRequest("POST", "/api/webhook", nil) req.Header.Set("X-Gitlab-Event", "Push Hook") eventJSON, err := os.ReadFile("testdata/gitlab-event.json") @@ -169,7 +239,7 @@ func TestGitLabPushEvent(t *testing.T) { func TestInvalidMethod(t *testing.T) { hook := test.NewGlobal() - h := NewMockHandler() + h := NewMockHandler(nil) req := httptest.NewRequest("GET", "/api/webhook", nil) req.Header.Set("X-GitHub-Event", "push") w := httptest.NewRecorder() @@ -183,7 +253,7 @@ func TestInvalidMethod(t *testing.T) { func TestInvalidEvent(t *testing.T) { hook := test.NewGlobal() - h := NewMockHandler() + h := NewMockHandler(nil) req := httptest.NewRequest("POST", "/api/webhook", nil) req.Header.Set("X-GitHub-Event", "push") w := httptest.NewRecorder() @@ -197,7 +267,7 @@ func TestInvalidEvent(t *testing.T) { func TestUnknownEvent(t *testing.T) { hook := test.NewGlobal() - h := NewMockHandler() + h := NewMockHandler(nil) req := httptest.NewRequest("POST", "/api/webhook", nil) req.Header.Set("X-Unknown-Event", "push") w := httptest.NewRecorder() @@ -215,94 +285,114 @@ func getApp(annotation string, sourcePath string) *v1alpha1.Application { }, }, Spec: v1alpha1.ApplicationSpec{ - Source: v1alpha1.ApplicationSource{ + Source: &v1alpha1.ApplicationSource{ Path: sourcePath, }, }, } } +func getMultiSourceApp(annotation string, paths ...string) *v1alpha1.Application { + var sources v1alpha1.ApplicationSources + for _, path := range paths { + sources = append(sources, v1alpha1.ApplicationSource{Path: path}) + } + return &v1alpha1.Application{ + ObjectMeta: metav1.ObjectMeta{ + Annotations: map[string]string{ + v1alpha1.AnnotationKeyManifestGeneratePaths: annotation, + }, + }, + Spec: v1alpha1.ApplicationSpec{ + Sources: sources, + }, + } +} + func Test_getAppRefreshPrefix(t *testing.T) { tests := []struct { - name string - app *v1alpha1.Application - files []string - want bool + name string + app *v1alpha1.Application + files []string + changeExpected bool }{ {"default no path", &v1alpha1.Application{}, []string{"README.md"}, true}, {"relative path - matching", getApp(".", "source/path"), []string{"source/path/my-deployment.yaml"}, true}, + {"relative path, multi source - matching #1", getMultiSourceApp(".", "source/path", "other/path"), []string{"source/path/my-deployment.yaml"}, true}, + {"relative path, multi source - matching #2", getMultiSourceApp(".", "other/path", "source/path"), []string{"source/path/my-deployment.yaml"}, true}, {"relative path - not matching", getApp(".", "source/path"), []string{"README.md"}, false}, + {"relative path, multi source - not matching", getMultiSourceApp(".", "other/path", "unrelated/path"), []string{"README.md"}, false}, {"absolute path - matching", getApp("/source/path", "source/path"), []string{"source/path/my-deployment.yaml"}, true}, + {"absolute path, multi source - matching #1", getMultiSourceApp("/source/path", "source/path", "other/path"), []string{"source/path/my-deployment.yaml"}, true}, + {"absolute path, multi source - matching #2", getMultiSourceApp("/source/path", "other/path", "source/path"), []string{"source/path/my-deployment.yaml"}, true}, {"absolute path - not matching", getApp("/source/path1", "source/path"), []string{"source/path/my-deployment.yaml"}, false}, + {"absolute path, multi source - not matching", getMultiSourceApp("/source/path1", "other/path", "source/path"), []string{"source/path/my-deployment.yaml"}, false}, {"two relative paths - matching", getApp(".;../shared", "my-app"), []string{"shared/my-deployment.yaml"}, true}, + {"two relative paths, multi source - matching #1", getMultiSourceApp(".;../shared", "my-app", "other/path"), []string{"shared/my-deployment.yaml"}, true}, + {"two relative paths, multi source - matching #2", getMultiSourceApp(".;../shared", "my-app", "other/path"), []string{"shared/my-deployment.yaml"}, true}, {"two relative paths - not matching", getApp(".;../shared", "my-app"), []string{"README.md"}, false}, + {"two relative paths, multi source - not matching", getMultiSourceApp(".;../shared", "my-app", "other/path"), []string{"README.md"}, false}, {"file relative path - matching", getApp("./my-deployment.yaml", "source/path"), []string{"source/path/my-deployment.yaml"}, true}, + {"file relative path, multi source - matching #1", getMultiSourceApp("./my-deployment.yaml", "source/path", "other/path"), []string{"source/path/my-deployment.yaml"}, true}, + {"file relative path, multi source - matching #2", getMultiSourceApp("./my-deployment.yaml", "other/path", "source/path"), []string{"source/path/my-deployment.yaml"}, true}, {"file relative path - not matching", getApp("./my-deployment.yaml", "source/path"), []string{"README.md"}, false}, + {"file relative path, multi source - not matching", getMultiSourceApp("./my-deployment.yaml", "source/path", "other/path"), []string{"README.md"}, false}, {"file absolute path - matching", getApp("/source/path/my-deployment.yaml", "source/path"), []string{"source/path/my-deployment.yaml"}, true}, + {"file absolute path, multi source - matching #1", getMultiSourceApp("/source/path/my-deployment.yaml", "source/path", "other/path"), []string{"source/path/my-deployment.yaml"}, true}, + {"file absolute path, multi source - matching #2", getMultiSourceApp("/source/path/my-deployment.yaml", "other/path", "source/path"), []string{"source/path/my-deployment.yaml"}, true}, {"file absolute path - not matching", getApp("/source/path1/README.md", "source/path"), []string{"source/path/my-deployment.yaml"}, false}, + {"file absolute path, multi source - not matching", getMultiSourceApp("/source/path1/README.md", "source/path", "other/path"), []string{"source/path/my-deployment.yaml"}, false}, {"file two relative paths - matching", getApp("./README.md;../shared/my-deployment.yaml", "my-app"), []string{"shared/my-deployment.yaml"}, true}, + {"file two relative paths, multi source - matching", getMultiSourceApp("./README.md;../shared/my-deployment.yaml", "my-app", "other-path"), []string{"shared/my-deployment.yaml"}, true}, {"file two relative paths - not matching", getApp(".README.md;../shared/my-deployment.yaml", "my-app"), []string{"kustomization.yaml"}, false}, + {"file two relative paths, multi source - not matching", getMultiSourceApp(".README.md;../shared/my-deployment.yaml", "my-app", "other-path"), []string{"kustomization.yaml"}, false}, } for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if got := appFilesHaveChanged(tt.app, tt.files); got != tt.want { - t.Errorf("getAppRefreshPrefix() = %v, want %v", got, tt.want) + ttc := tt + t.Run(ttc.name, func(t *testing.T) { + t.Parallel() + if got := appFilesHaveChanged(ttc.app, ttc.files); got != ttc.changeExpected { + t.Errorf("getAppRefreshPrefix() = %v, want %v", got, ttc.changeExpected) } }) } } func TestAppRevisionHasChanged(t *testing.T) { - assert.True(t, appRevisionHasChanged(&v1alpha1.Application{Spec: v1alpha1.ApplicationSpec{ - Source: v1alpha1.ApplicationSource{}, - }}, "master", true)) - - assert.False(t, appRevisionHasChanged(&v1alpha1.Application{Spec: v1alpha1.ApplicationSpec{ - Source: v1alpha1.ApplicationSource{}, - }}, "master", false)) - - assert.False(t, appRevisionHasChanged(&v1alpha1.Application{Spec: v1alpha1.ApplicationSpec{ - Source: v1alpha1.ApplicationSource{ - TargetRevision: "dev", - }, - }}, "master", true)) - - assert.True(t, appRevisionHasChanged(&v1alpha1.Application{Spec: v1alpha1.ApplicationSpec{ - Source: v1alpha1.ApplicationSource{ - TargetRevision: "dev", - }, - }}, "dev", false)) + getSource := func(targetRevision string) v1alpha1.ApplicationSource { + return v1alpha1.ApplicationSource{TargetRevision: targetRevision} + } - assert.False(t, appRevisionHasChanged(&v1alpha1.Application{Spec: v1alpha1.ApplicationSpec{ - Source: v1alpha1.ApplicationSource{ - TargetRevision: "refs/heads/dev", - }, - }}, "master", true)) + testCases := []struct { + name string + source v1alpha1.ApplicationSource + revision string + touchedHead bool + expectHasChanged bool + }{ + {"no target revision, master, touched head", getSource(""), "master", true, true}, + {"no target revision, master, did not touch head", getSource(""), "master", false, false}, + {"dev target revision, master, touched head", getSource("dev"), "master", true, false}, + {"dev target revision, dev, did not touch head", getSource("dev"), "dev", false, true}, + {"refs/heads/dev target revision, master, touched head", getSource("refs/heads/dev"), "master", true, false}, + {"refs/heads/dev target revision, dev, did not touch head", getSource("refs/heads/dev"), "dev", false, true}, + {"env/test target revision, env/test, did not touch head", getSource("env/test"), "env/test", false, true}, + {"refs/heads/env/test target revision, env/test, did not touch head", getSource("refs/heads/env/test"), "env/test", false, true}, + } - assert.True(t, appRevisionHasChanged(&v1alpha1.Application{Spec: v1alpha1.ApplicationSpec{ - Source: v1alpha1.ApplicationSource{ - TargetRevision: "refs/heads/dev", - }, - }}, "dev", false)) - assert.True(t, appRevisionHasChanged(&v1alpha1.Application{Spec: v1alpha1.ApplicationSpec{ - Source: v1alpha1.ApplicationSource{ - TargetRevision: "env/test", - }, - }}, "env/test", false)) - assert.True(t, appRevisionHasChanged(&v1alpha1.Application{Spec: v1alpha1.ApplicationSpec{ - Source: v1alpha1.ApplicationSource{ - TargetRevision: "refs/heads/env/test", - }, - }}, "env/test", false)) + for _, tc := range testCases { + tcc := tc + t.Run(tcc.name, func(t *testing.T) { + t.Parallel() + changed := sourceRevisionHasChanged(tcc.source, tcc.revision, tcc.touchedHead) + assert.Equal(t, tcc.expectHasChanged, changed) + }) + } } func Test_affectedRevisionInfo_appRevisionHasChanged(t *testing.T) { - appWithRevision := func(targetRevision string) *v1alpha1.Application { - return &v1alpha1.Application{Spec: v1alpha1.ApplicationSpec{ - Source: v1alpha1.ApplicationSource{ - TargetRevision: targetRevision, - }, - }} + sourceWithRevision := func(targetRevision string) v1alpha1.ApplicationSource { + return v1alpha1.ApplicationSource{TargetRevision: targetRevision} } githubPushPayload := func(branchName string) github.PushPayload { @@ -417,8 +507,8 @@ func Test_affectedRevisionInfo_appRevisionHasChanged(t *testing.T) { t.Run(testCopy.name, func(t *testing.T) { t.Parallel() _, revisionFromHook, _, _, _ := affectedRevisionInfo(testCopy.hookPayload) - if got := appRevisionHasChanged(appWithRevision(testCopy.targetRevision), revisionFromHook, false); got != testCopy.hasChanged { - t.Errorf("appRevisionHasChanged() = %v, want %v", got, testCopy.hasChanged) + if got := sourceRevisionHasChanged(sourceWithRevision(testCopy.targetRevision), revisionFromHook, false); got != testCopy.hasChanged { + t.Errorf("sourceRevisionHasChanged() = %v, want %v", got, testCopy.hasChanged) } }) } @@ -453,7 +543,7 @@ func Test_getWebUrlRegex(t *testing.T) { regexp, err := getWebUrlRegex(testCopy.webURL) assert.NoError(t, err) if matches := regexp.MatchString(testCopy.repo); matches != testCopy.shouldMatch { - t.Errorf("appRevisionHasChanged() = %v, want %v", matches, testCopy.shouldMatch) + t.Errorf("sourceRevisionHasChanged() = %v, want %v", matches, testCopy.shouldMatch) } }) }