diff --git a/.dockerignore b/.dockerignore index e778fce267438..12e17715871ca 100644 --- a/.dockerignore +++ b/.dockerignore @@ -17,6 +17,8 @@ manifests/ hack/ docs/ examples/ +.dockerignore +.git/ .github/ !test/container !test/e2e/testdata diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index b306343920656..4ddcc9e3afb64 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -5,7 +5,7 @@ contact_links: url: https://argo-cd.readthedocs.io/ about: Much help can be found in the docs - name: Ask a question - url: https://github.com/argoproj/argo-cd/discussions/new + url: https://github.com/codefresh-io/argo-cd/discussions/new about: Ask a question or start a discussion about Argo CD - name: Chat on Slack url: https://argoproj.github.io/community/join-slack diff --git a/.github/workflows/ci-build.yaml b/.github/workflows/ci-build.yaml index eaaf7946518d9..dd02b1aace2af 100644 --- a/.github/workflows/ci-build.yaml +++ b/.github/workflows/ci-build.yaml @@ -2,14 +2,16 @@ name: Integration tests on: push: branches: - - 'master' - - 'release-*' - - '!release-1.4' - - '!release-1.5' + - 'sync-*' + # - 'master' + # - 'release-*' + # - '!release-1.4' + # - '!release-1.5' pull_request: branches: - - 'master' - - 'release-*' + - 'sync-*' + # - 'master' + # - 'release-*' env: # Golang version to use across CI steps @@ -383,7 +385,7 @@ jobs: env: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} - name: Upload test results to Codecov - if: github.ref == 'refs/heads/master' && github.event_name == 'push' && github.repository == 'argoproj/argo-cd' + if: startsWith(github.ref, 'refs/heads/sync-') && github.event_name == 'push' && github.repository == 'codefresh-io/argo-cd' uses: codecov/test-results-action@9739113ad922ea0a9abb4b2c0f8bf6a4aa8ef820 # v1.0.1 with: file: test-results/junit.xml @@ -394,7 +396,7 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} uses: SonarSource/sonarqube-scan-action@bfd4e558cda28cda6b5defafb9232d191be8c203 # v4.2.1 - if: env.sonar_secret != '' + if: false && env.sonar_secret != '' test-e2e: name: Run end-to-end tests if: ${{ needs.changes.outputs.backend == 'true' }} diff --git a/.github/workflows/image.yaml b/.github/workflows/image.yaml index 1894455ceea32..1c2034f78ccbc 100644 --- a/.github/workflows/image.yaml +++ b/.github/workflows/image.yaml @@ -3,10 +3,10 @@ name: Image on: push: branches: - - master + - sync-* pull_request: branches: - - master + - sync-* types: [ labeled, unlabeled, opened, synchronize, reopened ] concurrency: @@ -19,17 +19,25 @@ jobs: set-vars: permissions: contents: read - if: github.repository == 'argoproj/argo-cd' + if: github.repository == 'codefresh-io/argo-cd' runs-on: ubuntu-22.04 outputs: - image-tag: ${{ steps.image.outputs.tag}} + image-tag: ${{ steps.image-pr.outputs.tag || steps.image-push.outputs.tag }} platforms: ${{ steps.platforms.outputs.platforms }} steps: - uses: actions/checkout@8410ad0602e1e429cee44a835ae9f77f654a6694 # v4.0.0 - - name: Set image tag for ghcr - run: echo "tag=$(cat ./VERSION)-${GITHUB_SHA::8}" >> $GITHUB_OUTPUT - id: image + - name: Set image tag (push to feature branch) + if: ${{ github.repository == 'codefresh-io/argo-cd' && github.event_name == 'pull_request' }} + run: | + CLEAN_REF=$(echo "${{ github.head_ref }}" | sed 's|^refs/[^/]*||; s|/|_|g') + echo "tag=v$(cat ./VERSION)-${CLEAN_REF}-${GITHUB_SHA::8}" >> $GITHUB_OUTPUT + id: image-pr + + - name: Set image tag (push to sync-* branch) + if: ${{ github.repository == 'codefresh-io/argo-cd' && github.event_name == 'push' }} + run: echo "tag=v$(cat ./VERSION)-$(date +%Y-%m-%d)-${GITHUB_SHA::8}" >> $GITHUB_OUTPUT + id: image-push - name: Determine image platforms to use id: platforms @@ -48,7 +56,7 @@ jobs: contents: read packages: write # for pushing packages to GHCR, which is used by cd.apps.argoproj.io to avoid polluting Quay with tags id-token: write # for creating OIDC tokens for signing. - if: ${{ github.repository == 'argoproj/argo-cd' && github.event_name != 'push' }} + if: ${{ false }} uses: ./.github/workflows/image-reuse.yaml with: # Note: cannot use env variables to set go-version (https://docs.github.com/en/actions/using-workflows/reusing-workflows#limitations) @@ -63,11 +71,11 @@ jobs: contents: read packages: write # for pushing packages to GHCR, which is used by cd.apps.argoproj.io to avoid polluting Quay with tags id-token: write # for creating OIDC tokens for signing. - if: ${{ github.repository == 'argoproj/argo-cd' && github.event_name == 'push' }} + if: ${{ github.repository == 'codefresh-io/argo-cd' }} uses: ./.github/workflows/image-reuse.yaml with: - quay_image_name: quay.io/argoproj/argocd:latest - ghcr_image_name: ghcr.io/argoproj/argo-cd/argocd:${{ needs.set-vars.outputs.image-tag }} + quay_image_name: ${{ github.event_name == 'pull_request' && 'quay.io/codefresh/dev/argocd' || 'quay.io/codefresh/argocd' }}:${{ needs.set-vars.outputs.image-tag }} + # ghcr_image_name: ghcr.io/codefresh-io/argo-cd/argocd:${{ needs.set-vars.outputs.image-tag }} # Note: cannot use env variables to set go-version (https://docs.github.com/en/actions/using-workflows/reusing-workflows#limitations) # renovate: datasource=golang-version packageName=golang go-version: 1.23.3 @@ -86,7 +94,7 @@ jobs: actions: read # for detecting the Github Actions environment. id-token: write # for creating OIDC tokens for signing. packages: write # for uploading attestations. (https://github.com/slsa-framework/slsa-github-generator/blob/main/internal/builders/container/README.md#known-issues) - if: ${{ github.repository == 'argoproj/argo-cd' && github.event_name == 'push' }} + if: ${{ false }} # Must be refernced by a tag. https://github.com/slsa-framework/slsa-github-generator/blob/main/internal/builders/container/README.md#referencing-the-slsa-generator uses: slsa-framework/slsa-github-generator/.github/workflows/generator_container_slsa3.yml@v2.0.0 with: @@ -103,7 +111,7 @@ jobs: permissions: contents: write # for git to push upgrade commit if not already deployed packages: write # for pushing packages to GHCR, which is used by cd.apps.argoproj.io to avoid polluting Quay with tags - if: ${{ github.repository == 'argoproj/argo-cd' && github.event_name == 'push' }} + if: ${{ false }} runs-on: ubuntu-22.04 steps: - uses: actions/checkout@8410ad0602e1e429cee44a835ae9f77f654a6694 # v4.0.0 diff --git a/.mockery.yaml b/.mockery.yaml index de7e1266f4dc8..4ba7ebe0bf824 100644 --- a/.mockery.yaml +++ b/.mockery.yaml @@ -77,3 +77,9 @@ packages: github.com/argoproj/argo-cd/v2/pkg/client/clientset/versioned/typed/application/v1alpha1: interfaces: AppProjectInterface: + github.com/argoproj/argo-cd/v2/acr_controller/application: + interfaces: + ApplicationClient: + github.com/argoproj/argo-cd/v2/event_reporter/application: + interfaces: + ApplicationClient: diff --git a/Dockerfile b/Dockerfile index 45c1deb4d8c9b..71fcfb464cebb 100644 --- a/Dockerfile +++ b/Dockerfile @@ -135,6 +135,8 @@ COPY --from=argocd-build /go/src/github.com/argoproj/argo-cd/dist/argocd* /usr/l USER root RUN ln -s /usr/local/bin/argocd /usr/local/bin/argocd-server && \ ln -s /usr/local/bin/argocd /usr/local/bin/argocd-repo-server && \ + ln -s /usr/local/bin/argocd /usr/local/bin/event-reporter-server && \ + ln -s /usr/local/bin/argocd /usr/local/bin/argocd-application-change-revision-controller && \ ln -s /usr/local/bin/argocd /usr/local/bin/argocd-cmp-server && \ ln -s /usr/local/bin/argocd /usr/local/bin/argocd-application-controller && \ ln -s /usr/local/bin/argocd /usr/local/bin/argocd-dex && \ diff --git a/Dockerfile.dev b/Dockerfile.dev index 978304f80fc44..b0193d477a017 100644 --- a/Dockerfile.dev +++ b/Dockerfile.dev @@ -7,6 +7,8 @@ COPY argocd /usr/local/bin/ USER root RUN ln -s /usr/local/bin/argocd /usr/local/bin/argocd-server && \ ln -s /usr/local/bin/argocd /usr/local/bin/argocd-repo-server && \ + ln -s /usr/local/bin/argocd /usr/local/bin/event-reporter-server && \ + ln -s /usr/local/bin/argocd /usr/local/bin/argocd-application-change-revision-controller && \ ln -s /usr/local/bin/argocd /usr/local/bin/argocd-application-controller && \ ln -s /usr/local/bin/argocd /usr/local/bin/argocd-dex && \ ln -s /usr/local/bin/argocd /usr/local/bin/argocd-notifications && \ diff --git a/Makefile b/Makefile index 8cc1b928dad83..201765d024bf3 100644 --- a/Makefile +++ b/Makefile @@ -125,6 +125,7 @@ define run-in-test-client -e GITHUB_TOKEN \ -e GOCACHE=/tmp/go-build-cache \ -e ARGOCD_LINT_GOGC=$(ARGOCD_LINT_GOGC) \ + -e GOSUMDB=off \ -v ${DOCKER_SRC_MOUNT} \ -v ${GOPATH}/pkg/mod:/go/pkg/mod${VOLUME_MOUNT} \ -v ${GOCACHE}:/tmp/go-build-cache${VOLUME_MOUNT} \ @@ -145,7 +146,7 @@ PATH:=$(PATH):$(PWD)/hack # docker image publishing options DOCKER_PUSH?=false -IMAGE_NAMESPACE?= +IMAGE_NAMESPACE?=quay.io/codefresh # perform static compilation STATIC_BUILD?=true # build development images @@ -532,7 +533,6 @@ start-local: mod-vendor-local dep-ui-local cli-local run: bash ./hack/goreman-start.sh - # Runs pre-commit validation with the virtualized toolchain .PHONY: pre-commit pre-commit: codegen build lint test diff --git a/Merge-upstream.md b/Merge-upstream.md new file mode 100644 index 0000000000000..3d89342abe566 --- /dev/null +++ b/Merge-upstream.md @@ -0,0 +1,46 @@ +## Resolving conflicts during upstream changes merge + +This docs include info about places where codefresh made it's customizations: + +#### General notes: +1. All files that're deleted in our branches - we can keep deleted (accept ours). +2. all `xxx.pb.go` - apply theirs and after resolving conflicts re-generate. + +#### Paths and actions on them +1. `.github/workflows` - accept ours (yours). +2. `applicationset` - accept theirs +3. `assets / swagger` - accept ours. Later run codegen and commit new version +4. `cmd / argocd` - accept ours if files deleted. +5. `cmd / argocd-application-controller` - no custom thing from our side, so just resolve conflicts. +6. `cmd / notifications` - no custom thing from our side, so just accept theirs. +7. `cmd / argocd-repo-server` - includes our changes with codefresh related parameters. +8. `cmd / common` - includes our changes with codefresh related constants (event-reporter) +9. `cmd / controller / application.go` - includes our changes to resource node (to return labels and annotations getResourceTree method) +10. `cmd / controller / state.go` - includes our changes (GetRepoObjs method) +11. `cmd / controller / state_test.go - includes our changes. Replace manifest values with our struct `apiclient.Manifest` +12. `docs` - apply theirs +13. `examples` - apply theirs +14. `hack` - apply theirs +15. `manifests` - accept theirs +16. `notification_controller` - apply theirs +17. `pkg/apis/application/v1alpha` - generatedXXX - apply theirs (than re-generate). types.go - merge (includes our changes with ForceNamespace). +18. `server / application.go` - merge (includes our v1 event-reporter.) +19. `ui` - accept theirs. +20. `util / kustomize` - merge, as it includes ours changes. +21. `mkdocs.yaml` - apply theirs. +22. `go.mod` - merge direct dependencies. go.sum accept theirs. Run go mod tidy. Check `replace` section, perform cleanup if needed. +23. `reposerver / sepository.go` - merge, includes: cf appVersion logic; type manifest struct (with path to file, rawManifest); + + +#### Post actions: +1. run `go mod tidy` +2. run `go mod download` +3. run `go mod vendor` +4. run `make lint-local` +5. run `make protogen-fast` - because sometimes gogen won't work if types from protogen used +6. run `make codegen` +7. run `make test-local` + +### Thoughts + +1. Revert cherry picks before merges - as they cause issues later if in upstream decided to slightly move some parts of such changes. In this case no conflicts will occur during merge as they on different lines but then you need cleanup them manually. \ No newline at end of file diff --git a/VERSION b/VERSION index d6961c361c3b3..75872a183a6c5 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.14.9 +2.14.10 diff --git a/acr_controller/application/client.go b/acr_controller/application/client.go new file mode 100644 index 0000000000000..296f0acb735a0 --- /dev/null +++ b/acr_controller/application/client.go @@ -0,0 +1,96 @@ +package application_change_revision_controller + +import ( + "context" + "crypto/tls" + "encoding/json" + "fmt" + "io" + "net/http" + "strings" + "time" + + "google.golang.org/grpc" + + appclient "github.com/argoproj/argo-cd/v2/pkg/apiclient/application" +) + +type ApplicationClient interface { + GetChangeRevision(ctx context.Context, in *appclient.ChangeRevisionRequest, opts ...grpc.CallOption) (*appclient.ChangeRevisionResponse, error) +} + +type httpApplicationClient struct { + httpClient *http.Client + baseUrl string + token string + rootpath string +} + +func NewHttpApplicationClient(token string, address string, rootpath string) ApplicationClient { + if rootpath != "" && !strings.HasPrefix(rootpath, "/") { + rootpath = "/" + rootpath + } + + if !strings.Contains(address, "http") { + address = "http://" + address + } + + if rootpath != "" { + address = address + rootpath + } + + return &httpApplicationClient{ + httpClient: &http.Client{ + Timeout: 30 * time.Second, + Transport: &http.Transport{ + // Support for insecure connections + TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, + }, + }, + baseUrl: address, + token: token, + rootpath: rootpath, + } +} + +func (c *httpApplicationClient) execute(ctx context.Context, url string, result interface{}) error { + req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil) + if err != nil { + return err + } + + req.Header.Set("Content-Type", "application/json") + req.Header.Set("Authorization", "Bearer "+c.token) + + res, err := c.httpClient.Do(req) + if err != nil { + return err + } + defer res.Body.Close() + + b, _ := io.ReadAll(res.Body) + + isStatusOK := res.StatusCode >= 200 && res.StatusCode < 300 + if !isStatusOK { + return fmt.Errorf("argocd server respond with code %d, msg is: %s", res.StatusCode, string(b)) + } + + err = json.Unmarshal(b, &result) + if err != nil { + return err + } + return nil +} + +func (c *httpApplicationClient) GetChangeRevision(ctx context.Context, in *appclient.ChangeRevisionRequest, opts ...grpc.CallOption) (*appclient.ChangeRevisionResponse, error) { + params := fmt.Sprintf("?appName=%s&namespace=%s¤tRevision=%s&previousRevision=%s", in.GetAppName(), in.GetNamespace(), in.GetCurrentRevision(), in.GetPreviousRevision()) + + url := fmt.Sprintf("%s/api/v1/application/changeRevision%s", c.baseUrl, params) + + changeRevisionResponse := &appclient.ChangeRevisionResponse{} + err := c.execute(ctx, url, changeRevisionResponse) + if err != nil { + return nil, err + } + return changeRevisionResponse, nil +} diff --git a/acr_controller/application/mocks/ApplicationClient.go b/acr_controller/application/mocks/ApplicationClient.go new file mode 100644 index 0000000000000..096a337652421 --- /dev/null +++ b/acr_controller/application/mocks/ApplicationClient.go @@ -0,0 +1,69 @@ +// Code generated by mockery v2.43.2. DO NOT EDIT. + +package mocks + +import ( + application "github.com/argoproj/argo-cd/v2/pkg/apiclient/application" + + context "context" + + grpc "google.golang.org/grpc" + + mock "github.com/stretchr/testify/mock" +) + +// ApplicationClient is an autogenerated mock type for the ApplicationClient type +type ApplicationClient struct { + mock.Mock +} + +// GetChangeRevision provides a mock function with given fields: ctx, in, opts +func (_m *ApplicationClient) GetChangeRevision(ctx context.Context, in *application.ChangeRevisionRequest, opts ...grpc.CallOption) (*application.ChangeRevisionResponse, error) { + _va := make([]interface{}, len(opts)) + for _i := range opts { + _va[_i] = opts[_i] + } + var _ca []interface{} + _ca = append(_ca, ctx, in) + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + if len(ret) == 0 { + panic("no return value specified for GetChangeRevision") + } + + var r0 *application.ChangeRevisionResponse + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *application.ChangeRevisionRequest, ...grpc.CallOption) (*application.ChangeRevisionResponse, error)); ok { + return rf(ctx, in, opts...) + } + if rf, ok := ret.Get(0).(func(context.Context, *application.ChangeRevisionRequest, ...grpc.CallOption) *application.ChangeRevisionResponse); ok { + r0 = rf(ctx, in, opts...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*application.ChangeRevisionResponse) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *application.ChangeRevisionRequest, ...grpc.CallOption) error); ok { + r1 = rf(ctx, in, opts...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// NewApplicationClient creates a new instance of ApplicationClient. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewApplicationClient(t interface { + mock.TestingT + Cleanup(func()) +}) *ApplicationClient { + mock := &ApplicationClient{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/acr_controller/controller/broadcaster.go b/acr_controller/controller/broadcaster.go new file mode 100644 index 0000000000000..9056e92203eeb --- /dev/null +++ b/acr_controller/controller/broadcaster.go @@ -0,0 +1,107 @@ +package application_change_revision_controller + +import ( + "sync" + + log "github.com/sirupsen/logrus" + "k8s.io/apimachinery/pkg/watch" + + appv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" +) + +type subscriber struct { + ch chan *appv1.ApplicationWatchEvent + filters []func(*appv1.ApplicationWatchEvent) bool +} + +func (s *subscriber) matches(event *appv1.ApplicationWatchEvent) bool { + for i := range s.filters { + if !s.filters[i](event) { + return false + } + } + return true +} + +// Broadcaster is an interface for broadcasting application informer watch events to multiple subscribers. +type Broadcaster interface { + Subscribe(ch chan *appv1.ApplicationWatchEvent, filters ...func(event *appv1.ApplicationWatchEvent) bool) func() + OnAdd(interface{}, bool) + OnUpdate(interface{}, interface{}) + OnDelete(interface{}) +} + +type broadcasterHandler struct { + lock sync.Mutex + subscribers []*subscriber +} + +func NewBroadcaster() Broadcaster { + return &broadcasterHandler{} +} + +func (b *broadcasterHandler) notify(event *appv1.ApplicationWatchEvent) { + val, ok := event.Application.Annotations[appv1.AnnotationKeyManifestGeneratePaths] + if !ok || val == "" { + return + } + + // Make a local copy of b.subscribers, then send channel events outside the lock, + // to avoid data race on b.subscribers changes + subscribers := []*subscriber{} + b.lock.Lock() + subscribers = append(subscribers, b.subscribers...) + b.lock.Unlock() + + for _, s := range subscribers { + if s.matches(event) { + select { + case s.ch <- event: + { + // log.Infof("adding application '%s' to channel", event.Application.Name) + } + default: + // drop event if cannot send right away + log.WithField("application", event.Application.Name).Warn("unable to send event notification") + } + } + } +} + +// Subscribe forward application informer watch events to the provided channel. +// The watch events are dropped if no receives are reading events from the channel so the channel must have +// buffer if dropping events is not acceptable. +func (b *broadcasterHandler) Subscribe(ch chan *appv1.ApplicationWatchEvent, filters ...func(event *appv1.ApplicationWatchEvent) bool) func() { + b.lock.Lock() + defer b.lock.Unlock() + subscriber := &subscriber{ch, filters} + b.subscribers = append(b.subscribers, subscriber) + return func() { + b.lock.Lock() + defer b.lock.Unlock() + for i := range b.subscribers { + if b.subscribers[i] == subscriber { + b.subscribers = append(b.subscribers[:i], b.subscribers[i+1:]...) + break + } + } + } +} + +func (b *broadcasterHandler) OnAdd(obj interface{}, isInInitialList bool) { + if app, ok := obj.(*appv1.Application); ok { + b.notify(&appv1.ApplicationWatchEvent{Application: *app, Type: watch.Added}) + } +} + +func (b *broadcasterHandler) OnUpdate(_, newObj interface{}) { + if app, ok := newObj.(*appv1.Application); ok { + b.notify(&appv1.ApplicationWatchEvent{Application: *app, Type: watch.Modified}) + } +} + +func (b *broadcasterHandler) OnDelete(obj interface{}) { + if app, ok := obj.(*appv1.Application); ok { + b.notify(&appv1.ApplicationWatchEvent{Application: *app, Type: watch.Deleted}) + } +} diff --git a/acr_controller/controller/controller.go b/acr_controller/controller/controller.go new file mode 100644 index 0000000000000..f759fd4e4076e --- /dev/null +++ b/acr_controller/controller/controller.go @@ -0,0 +1,82 @@ +package application_change_revision_controller + +import ( + "context" + "time" + + log "github.com/sirupsen/logrus" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" + + appclient "github.com/argoproj/argo-cd/v2/acr_controller/application" + "github.com/argoproj/argo-cd/v2/acr_controller/service" + appclientset "github.com/argoproj/argo-cd/v2/pkg/client/clientset/versioned" + + appv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + applisters "github.com/argoproj/argo-cd/v2/pkg/client/listers/application/v1alpha1" + servercache "github.com/argoproj/argo-cd/v2/server/cache" +) + +var watchAPIBufferSize = 1000 + +type ACRController interface { + Run(ctx context.Context) +} + +type applicationChangeRevisionController struct { + appBroadcaster Broadcaster + cache *servercache.Cache + appLister applisters.ApplicationLister + applicationServiceClient appclient.ApplicationClient + acrService service.ACRService + applicationClientset appclientset.Interface +} + +func NewApplicationChangeRevisionController(appInformer cache.SharedIndexInformer, cache *servercache.Cache, applicationServiceClient appclient.ApplicationClient, appLister applisters.ApplicationLister, applicationClientset appclientset.Interface) ACRController { + appBroadcaster := NewBroadcaster() + _, err := appInformer.AddEventHandler(appBroadcaster) + if err != nil { + log.Error(err) + } + return &applicationChangeRevisionController{ + appBroadcaster: appBroadcaster, + cache: cache, + applicationServiceClient: applicationServiceClient, + appLister: appLister, + applicationClientset: applicationClientset, + acrService: service.NewACRService(applicationClientset, applicationServiceClient), + } +} + +func (c *applicationChangeRevisionController) Run(ctx context.Context) { + var logCtx log.FieldLogger = log.StandardLogger() + + calculateIfPermitted := func(ctx context.Context, a appv1.Application, eventType watch.EventType, ts string) error { //nolint:golint,unparam + if eventType == watch.Bookmark || eventType == watch.Deleted { + return nil // ignore this event + } + + return c.acrService.ChangeRevision(ctx, &a) + } + + // TODO: move to abstraction + eventsChannel := make(chan *appv1.ApplicationWatchEvent, watchAPIBufferSize) + unsubscribe := c.appBroadcaster.Subscribe(eventsChannel) + defer unsubscribe() + for { + select { + case <-ctx.Done(): + return + case event := <-eventsChannel: + // logCtx.Infof("channel size is %d", len(eventsChannel)) + + ts := time.Now().Format("2006-01-02T15:04:05.000Z") + ctx, cancel := context.WithTimeout(ctx, 2*time.Minute) + err := calculateIfPermitted(ctx, event.Application, event.Type, ts) + if err != nil { + logCtx.WithError(err).Error("failed to calculate change revision") + } + cancel() + } + } +} diff --git a/acr_controller/server.go b/acr_controller/server.go new file mode 100644 index 0000000000000..f9afb5d755678 --- /dev/null +++ b/acr_controller/server.go @@ -0,0 +1,207 @@ +package acr_controller + +import ( + "context" + "crypto/tls" + "fmt" + "net" + "net/http" + "time" + + "github.com/redis/go-redis/v9" + log "github.com/sirupsen/logrus" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/wait" + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/tools/cache" + + appclient "github.com/argoproj/argo-cd/v2/acr_controller/application" + acr_controller "github.com/argoproj/argo-cd/v2/acr_controller/controller" + + appclientset "github.com/argoproj/argo-cd/v2/pkg/client/clientset/versioned" + appinformer "github.com/argoproj/argo-cd/v2/pkg/client/informers/externalversions" + applisters "github.com/argoproj/argo-cd/v2/pkg/client/listers/application/v1alpha1" + servercache "github.com/argoproj/argo-cd/v2/server/cache" + "github.com/argoproj/argo-cd/v2/util/healthz" + settings_util "github.com/argoproj/argo-cd/v2/util/settings" +) + +var backoff = wait.Backoff{ + Steps: 5, + Duration: 500 * time.Millisecond, + Factor: 1.0, + Jitter: 0.1, +} + +type ACRServer struct { + ACRServerOpts + + settings *settings_util.ArgoCDSettings + log *log.Entry + appInformer cache.SharedIndexInformer + appLister applisters.ApplicationLister + applicationClientset appclientset.Interface + + // stopCh is the channel which when closed, will shutdown the Event Reporter server + stopCh chan struct{} + serviceSet *ACRServerSet +} + +type ACRServerSet struct{} + +type ACRServerOpts struct { + ListenPort int + ListenHost string + Namespace string + KubeClientset kubernetes.Interface + AppClientset appclientset.Interface + ApplicationServiceClient appclient.ApplicationClient + Cache *servercache.Cache + RedisClient *redis.Client + ApplicationNamespaces []string + BaseHRef string + RootPath string +} + +type handlerSwitcher struct { + handler http.Handler + urlToHandler map[string]http.Handler + contentTypeToHandler map[string]http.Handler +} + +type Listeners struct { + Main net.Listener +} + +func (l *Listeners) Close() error { + if l.Main != nil { + if err := l.Main.Close(); err != nil { + return err + } + l.Main = nil + } + return nil +} + +func (s *handlerSwitcher) ServeHTTP(w http.ResponseWriter, r *http.Request) { + if urlHandler, ok := s.urlToHandler[r.URL.Path]; ok { + urlHandler.ServeHTTP(w, r) + } else if contentHandler, ok := s.contentTypeToHandler[r.Header.Get("content-type")]; ok { + contentHandler.ServeHTTP(w, r) + } else { + s.handler.ServeHTTP(w, r) + } +} + +func (a *ACRServer) healthCheck(r *http.Request) error { + return nil +} + +// Init starts informers used by the API server +func (a *ACRServer) Init(ctx context.Context) { + go a.appInformer.Run(ctx.Done()) + svcSet := newApplicationChangeRevisionServiceSet() + a.serviceSet = svcSet +} + +func (a *ACRServer) RunController(ctx context.Context) { + controller := acr_controller.NewApplicationChangeRevisionController(a.appInformer, a.Cache, a.ApplicationServiceClient, a.appLister, a.applicationClientset) + go controller.Run(ctx) +} + +// newHTTPServer returns the HTTP server to serve HTTP/HTTPS requests. This is implemented +// using grpc-gateway as a proxy to the gRPC server. +func (a *ACRServer) newHTTPServer(ctx context.Context, port int) *http.Server { //nolint:golint,unparam + endpoint := fmt.Sprintf("localhost:%d", port) + mux := http.NewServeMux() + httpS := http.Server{ + Addr: endpoint, + Handler: &handlerSwitcher{ + handler: mux, + }, + } + + healthz.ServeHealthCheck(mux, a.healthCheck) + return &httpS +} + +func (a *ACRServer) checkServeErr(name string, err error) { + if err != nil { + if a.stopCh == nil { + // a nil stopCh indicates a graceful shutdown + log.Infof("graceful shutdown %s: %v", name, err) + } else { + log.Fatalf("%s: %v", name, err) + } + } else { + log.Infof("graceful shutdown %s", name) + } +} + +func startListener(host string, port int) (net.Listener, error) { + var conn net.Listener + var realErr error + _ = wait.ExponentialBackoff(backoff, func() (bool, error) { + conn, realErr = net.Listen("tcp", fmt.Sprintf("%s:%d", host, port)) + if realErr != nil { + return false, nil + } + return true, nil + }) + return conn, realErr +} + +func (a *ACRServer) Listen() (*Listeners, error) { + mainLn, err := startListener(a.ListenHost, a.ListenPort) + if err != nil { + return nil, err + } + return &Listeners{Main: mainLn}, nil +} + +// Run runs the API Server +// We use k8s.io/code-generator/cmd/go-to-protobuf to generate the .proto files from the API types. +// k8s.io/ go-to-protobuf uses protoc-gen-gogo, which comes from gogo/protobuf (a fork of +// golang/protobuf). +func (a *ACRServer) Run(ctx context.Context, lns *Listeners) { + httpS := a.newHTTPServer(ctx, a.ListenPort) + tlsConfig := tls.Config{} + tlsConfig.GetCertificate = func(info *tls.ClientHelloInfo) (*tls.Certificate, error) { + return a.settings.Certificate, nil + } + go func() { a.checkServeErr("httpS", httpS.Serve(lns.Main)) }() + go a.RunController(ctx) + + if !cache.WaitForCacheSync(ctx.Done(), a.appInformer.HasSynced) { + log.Fatal("Timed out waiting for project cache to sync") + } + + a.stopCh = make(chan struct{}) + <-a.stopCh +} + +// NewServer returns a new instance of the Event Reporter server +func NewApplicationChangeRevisionServer(ctx context.Context, opts ACRServerOpts) *ACRServer { + appInformerNs := opts.Namespace + if len(opts.ApplicationNamespaces) > 0 { + appInformerNs = "" + } + appFactory := appinformer.NewSharedInformerFactoryWithOptions(opts.AppClientset, 0, appinformer.WithNamespace(appInformerNs), appinformer.WithTweakListOptions(func(options *metav1.ListOptions) {})) + + appInformer := appFactory.Argoproj().V1alpha1().Applications().Informer() + appLister := appFactory.Argoproj().V1alpha1().Applications().Lister() + + server := &ACRServer{ + ACRServerOpts: opts, + log: log.NewEntry(log.StandardLogger()), + appInformer: appInformer, + appLister: appLister, + applicationClientset: opts.AppClientset, + } + + return server +} + +func newApplicationChangeRevisionServiceSet() *ACRServerSet { + return &ACRServerSet{} +} diff --git a/acr_controller/service/acr_service.go b/acr_controller/service/acr_service.go new file mode 100644 index 0000000000000..665ecbb75fd3a --- /dev/null +++ b/acr_controller/service/acr_service.go @@ -0,0 +1,202 @@ +package service + +import ( + "context" + "encoding/json" + "sync" + + log "github.com/sirupsen/logrus" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" + "k8s.io/utils/ptr" + + argoclient "github.com/argoproj/argo-cd/v2/acr_controller/application" + appclient "github.com/argoproj/argo-cd/v2/pkg/apiclient/application" + application "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + appclientset "github.com/argoproj/argo-cd/v2/pkg/client/clientset/versioned" +) + +type ACRService interface { + ChangeRevision(ctx context.Context, application *application.Application) error +} + +type acrService struct { + applicationClientset appclientset.Interface + applicationServiceClient argoclient.ApplicationClient + lock sync.Mutex + logger *log.Logger +} + +func NewACRService(applicationClientset appclientset.Interface, applicationServiceClient argoclient.ApplicationClient) ACRService { + return &acrService{ + applicationClientset: applicationClientset, + applicationServiceClient: applicationServiceClient, + logger: log.New(), + } +} + +func getChangeRevisionFromRevisions(revisions []string) string { + if len(revisions) > 0 { + return revisions[0] + } + return "" +} + +func getChangeRevision(app *application.Application) string { + if app.Status.OperationState != nil && app.Status.OperationState.Operation.Sync != nil { + changeRevision := app.Status.OperationState.Operation.Sync.ChangeRevision + if changeRevision != "" { + return changeRevision + } + if changeRevision = getChangeRevisionFromRevisions(app.Status.OperationState.Operation.Sync.ChangeRevisions); changeRevision != "" { + return changeRevision + } + } + return "" +} + +func (c *acrService) ChangeRevision(ctx context.Context, a *application.Application) error { + c.lock.Lock() + defer c.lock.Unlock() + + app, err := c.applicationClientset.ArgoprojV1alpha1().Applications(a.Namespace).Get(ctx, a.Name, metav1.GetOptions{}) + if err != nil { + return err + } + + if app.Operation == nil || app.Operation.Sync == nil { + return nil + } + + if getChangeRevision(app) != "" { + c.logger.Infof("Change revision already calculated for application %s", app.Name) + return nil + } + + revision, err := c.calculateRevision(ctx, app) + if err != nil { + return err + } + + if revision == nil || *revision == "" { + c.logger.Infof("Revision for application %s is empty", app.Name) + return nil + } + + c.logger.Infof("Change revision for application %s is %s", app.Name, *revision) + + app, err = c.applicationClientset.ArgoprojV1alpha1().Applications(app.Namespace).Get(ctx, app.Name, metav1.GetOptions{}) + if err != nil { + return err + } + + revisions := []string{*revision} + + if app.Status.OperationState != nil && app.Status.OperationState.Operation.Sync != nil { + c.logger.Infof("Patch operation status for application %s", app.Name) + return c.patchOperationSyncResultWithChangeRevision(ctx, app, revisions) + } + + c.logger.Infof("Patch operation for application %s", app.Name) + return c.patchOperationWithChangeRevision(ctx, app, revisions) +} + +func (c *acrService) calculateRevision(ctx context.Context, a *application.Application) (*string, error) { + currentRevision, previousRevision := c.getRevisions(ctx, a) + c.logger.Infof("Calculate revision for application '%s', current revision '%s', previous revision '%s'", a.Name, currentRevision, previousRevision) + changeRevisionResult, err := c.applicationServiceClient.GetChangeRevision(ctx, &appclient.ChangeRevisionRequest{ + AppName: ptr.To(a.GetName()), + Namespace: ptr.To(a.GetNamespace()), + CurrentRevision: ptr.To(currentRevision), + PreviousRevision: ptr.To(previousRevision), + }) + if err != nil { + return nil, err + } + return changeRevisionResult.Revision, nil +} + +func (c *acrService) patchOperationWithChangeRevision(ctx context.Context, a *application.Application, revisions []string) error { + if len(revisions) == 1 { + patch, _ := json.Marshal(map[string]interface{}{ + "operation": map[string]interface{}{ + "sync": map[string]interface{}{ + "changeRevision": revisions[0], + }, + }, + }) + _, err := c.applicationClientset.ArgoprojV1alpha1().Applications(a.Namespace).Patch(ctx, a.Name, types.MergePatchType, patch, metav1.PatchOptions{}) + return err + } + + patch, _ := json.Marshal(map[string]interface{}{ + "operation": map[string]interface{}{ + "sync": map[string]interface{}{ + "changeRevisions": revisions, + }, + }, + }) + _, err := c.applicationClientset.ArgoprojV1alpha1().Applications(a.Namespace).Patch(ctx, a.Name, types.MergePatchType, patch, metav1.PatchOptions{}) + return err +} + +func (c *acrService) patchOperationSyncResultWithChangeRevision(ctx context.Context, a *application.Application, revisions []string) error { + if len(revisions) == 1 { + patch, _ := json.Marshal(map[string]interface{}{ + "status": map[string]interface{}{ + "operationState": map[string]interface{}{ + "operation": map[string]interface{}{ + "sync": map[string]interface{}{ + "changeRevision": revisions[0], + }, + }, + }, + }, + }) + _, err := c.applicationClientset.ArgoprojV1alpha1().Applications(a.Namespace).Patch(ctx, a.Name, types.MergePatchType, patch, metav1.PatchOptions{}) + return err + } + + patch, _ := json.Marshal(map[string]interface{}{ + "status": map[string]interface{}{ + "operationState": map[string]interface{}{ + "operation": map[string]interface{}{ + "sync": map[string]interface{}{ + "changeRevisions": revisions, + }, + }, + }, + }, + }) + _, err := c.applicationClientset.ArgoprojV1alpha1().Applications(a.Namespace).Patch(ctx, a.Name, types.MergePatchType, patch, metav1.PatchOptions{}) + return err +} + +func getCurrentRevisionFromOperation(a *application.Application) string { + if a.Operation != nil && a.Operation.Sync != nil { + return a.Operation.Sync.Revision + } + return "" +} + +func (c *acrService) getRevisions(_ context.Context, a *application.Application) (string, string) { + if len(a.Status.History) == 0 { + // it is first sync operation, and we have only current revision + return getCurrentRevisionFromOperation(a), "" + } + + // in case if sync is already done, we need to use revision from sync result and previous revision from history + if a.Status.Sync.Status == "Synced" && a.Status.OperationState != nil && a.Status.OperationState.SyncResult != nil { + currentRevision := a.Status.OperationState.SyncResult.Revision + // in case if we have only one history record, we need to return empty previous revision, because it is first sync result + if len(a.Status.History) == 1 { + return currentRevision, "" + } + return currentRevision, a.Status.History[len(a.Status.History)-2].Revision + } + + // in case if sync is in progress, we need to use revision from operation and revision from latest history record + currentRevision := getCurrentRevisionFromOperation(a) + previousRevision := a.Status.History[len(a.Status.History)-1].Revision + return currentRevision, previousRevision +} diff --git a/acr_controller/service/acr_service_test.go b/acr_controller/service/acr_service_test.go new file mode 100644 index 0000000000000..c4fe74125944e --- /dev/null +++ b/acr_controller/service/acr_service_test.go @@ -0,0 +1,319 @@ +package service + +import ( + "context" + "testing" + + "github.com/sirupsen/logrus" + test2 "github.com/sirupsen/logrus/hooks/test" + + "github.com/argoproj/argo-cd/v2/acr_controller/application/mocks" + appclient "github.com/argoproj/argo-cd/v2/pkg/apiclient/application" + appsv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + apps "github.com/argoproj/argo-cd/v2/pkg/client/clientset/versioned/fake" + "github.com/argoproj/argo-cd/v2/test" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/utils/ptr" + "sigs.k8s.io/yaml" +) + +const fakeApp = ` +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: test-app + namespace: default +spec: + source: + path: some/path + repoURL: https://github.com/argoproj/argocd-example-apps.git + targetRevision: HEAD + ksonnet: + environment: default + destination: + namespace: ` + test.FakeDestNamespace + ` + server: https://cluster-api.example.com +` + +const fakeAppWithOperation = ` +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + annotations: + argocd.argoproj.io/manifest-generate-paths: . + finalizers: + - resources-finalizer.argocd.argoproj.io + labels: + app.kubernetes.io/instance: guestbook + name: guestbook + namespace: codefresh +operation: + initiatedBy: + automated: true + retry: + limit: 5 + sync: + prune: true + revision: c732f4d2ef24c7eeb900e9211ff98f90bb646505 + syncOptions: + - CreateNamespace=true +spec: + destination: + namespace: guestbook + server: https://kubernetes.default.svc + project: default + source: + path: apps/guestbook + repoURL: https://github.com/pasha-codefresh/precisely-gitsource.git + targetRevision: HEAD +` + +const syncedAppWithSingleHistory = ` +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + annotations: + argocd.argoproj.io/manifest-generate-paths: . + finalizers: + - resources-finalizer.argocd.argoproj.io + labels: + app.kubernetes.io/instance: guestbook + name: guestbook + namespace: codefresh +operation: + initiatedBy: + automated: true + retry: + limit: 5 + sync: + prune: true + revision: c732f4d2ef24c7eeb900e9211ff98f90bb646505 + syncOptions: + - CreateNamespace=true +spec: + destination: + namespace: guestbook + server: https://kubernetes.default.svc + project: default + source: + path: apps/guestbook + repoURL: https://github.com/pasha-codefresh/precisely-gitsource.git + targetRevision: HEAD +status: + history: + - deployStartedAt: "2024-06-20T19:35:36Z" + deployedAt: "2024-06-20T19:35:44Z" + id: 3 + initiatedBy: {} + revision: 792822850fd2f6db63597533e16dfa27e6757dc5 + source: + path: apps/guestbook + repoURL: https://github.com/pasha-codefresh/precisely-gitsource.git + targetRevision: HEAD + operationState: + operation: + sync: + prune: true + revision: c732f4d2ef24c7eeb900e9211ff98f90bb646506 + syncOptions: + - CreateNamespace=true + phase: Running + startedAt: "2024-06-20T19:47:34Z" + syncResult: + revision: c732f4d2ef24c7eeb900e9211ff98f90bb646505 + source: + path: apps/guestbook + repoURL: https://github.com/pasha-codefresh/precisely-gitsource.git + targetRevision: HEAD + sync: + revision: 00d423763fbf56d2ea452de7b26a0ab20590f521 + status: Synced +` + +const syncedAppWithHistory = ` +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + annotations: + argocd.argoproj.io/manifest-generate-paths: . + finalizers: + - resources-finalizer.argocd.argoproj.io + labels: + app.kubernetes.io/instance: guestbook + name: guestbook + namespace: codefresh +operation: + initiatedBy: + automated: true + retry: + limit: 5 + sync: + prune: true + revision: c732f4d2ef24c7eeb900e9211ff98f90bb646505 + syncOptions: + - CreateNamespace=true +spec: + destination: + namespace: guestbook + server: https://kubernetes.default.svc + project: default + source: + path: apps/guestbook + repoURL: https://github.com/pasha-codefresh/precisely-gitsource.git + targetRevision: HEAD +status: + history: + - deployStartedAt: "2024-06-20T19:35:36Z" + deployedAt: "2024-06-20T19:35:44Z" + id: 3 + initiatedBy: {} + revision: 792822850fd2f6db63597533e16dfa27e6757dc5 + source: + path: apps/guestbook + repoURL: https://github.com/pasha-codefresh/precisely-gitsource.git + targetRevision: HEAD + - deployStartedAt: "2024-06-20T19:36:34Z" + deployedAt: "2024-06-20T19:36:42Z" + id: 4 + initiatedBy: {} + revision: ee5373eb9814e247ec6944e8b8897a8ec2f8528e + source: + path: apps/guestbook + repoURL: https://github.com/pasha-codefresh/precisely-gitsource.git + targetRevision: HEAD + operationState: + operation: + sync: + prune: true + revision: c732f4d2ef24c7eeb900e9211ff98f90bb646506 + syncOptions: + - CreateNamespace=true + phase: Running + startedAt: "2024-06-20T19:47:34Z" + syncResult: + revision: c732f4d2ef24c7eeb900e9211ff98f90bb646505 + source: + path: apps/guestbook + repoURL: https://github.com/pasha-codefresh/precisely-gitsource.git + targetRevision: HEAD + sync: + revision: 00d423763fbf56d2ea452de7b26a0ab20590f521 + status: Synced +` + +func newTestACRService(client *mocks.ApplicationClient) *acrService { + fakeAppsClientset := apps.NewSimpleClientset(createTestApp(syncedAppWithHistory)) + return &acrService{ + applicationClientset: fakeAppsClientset, + applicationServiceClient: client, + logger: logrus.New(), + } +} + +func createTestApp(testApp string, opts ...func(app *appsv1.Application)) *appsv1.Application { + var app appsv1.Application + err := yaml.Unmarshal([]byte(testApp), &app) + if err != nil { + panic(err) + } + for i := range opts { + opts[i](&app) + } + return &app +} + +func Test_getRevisions(r *testing.T) { + r.Run("history list is empty", func(t *testing.T) { + acrService := newTestACRService(&mocks.ApplicationClient{}) + current, previous := acrService.getRevisions(context.TODO(), createTestApp(fakeApp)) + assert.Equal(t, "", current) + assert.Equal(t, "", previous) + }) + + r.Run("history list is empty, but operation happens right now", func(t *testing.T) { + acrService := newTestACRService(&mocks.ApplicationClient{}) + current, previous := acrService.getRevisions(context.TODO(), createTestApp(fakeAppWithOperation)) + assert.Equal(t, "c732f4d2ef24c7eeb900e9211ff98f90bb646505", current) + assert.Equal(t, "", previous) + }) + + r.Run("history list contains only one element, also sync result is here", func(t *testing.T) { + acrService := newTestACRService(&mocks.ApplicationClient{}) + current, previous := acrService.getRevisions(context.TODO(), createTestApp(syncedAppWithSingleHistory)) + assert.Equal(t, "c732f4d2ef24c7eeb900e9211ff98f90bb646505", current) + assert.Equal(t, "", previous) + }) + + r.Run("application is synced", func(t *testing.T) { + acrService := newTestACRService(&mocks.ApplicationClient{}) + app := createTestApp(syncedAppWithHistory) + current, previous := acrService.getRevisions(context.TODO(), app) + assert.Equal(t, app.Status.OperationState.SyncResult.Revision, current) + assert.Equal(t, app.Status.History[len(app.Status.History)-2].Revision, previous) + }) + + r.Run("application sync is in progress", func(t *testing.T) { + acrService := newTestACRService(&mocks.ApplicationClient{}) + app := createTestApp(syncedAppWithHistory) + app.Status.Sync.Status = "Syncing" + current, previous := acrService.getRevisions(context.TODO(), app) + assert.Equal(t, app.Operation.Sync.Revision, current) + assert.Equal(t, app.Status.History[len(app.Status.History)-1].Revision, previous) + }) +} + +func Test_ChangeRevision(r *testing.T) { + r.Run("Change revision", func(t *testing.T) { + client := &mocks.ApplicationClient{} + client.On("GetChangeRevision", mock.Anything, mock.Anything).Return(&appclient.ChangeRevisionResponse{ + Revision: ptr.To("new-revision"), + }, nil) + acrService := newTestACRService(client) + app := createTestApp(syncedAppWithHistory) + + err := acrService.ChangeRevision(context.TODO(), app) + require.NoError(t, err) + + app, err = acrService.applicationClientset.ArgoprojV1alpha1().Applications(app.Namespace).Get(context.TODO(), app.Name, metav1.GetOptions{}) + require.NoError(t, err) + + assert.Equal(t, "new-revision", app.Status.OperationState.Operation.Sync.ChangeRevision) + }) + + r.Run("Change revision already exists", func(t *testing.T) { + client := &mocks.ApplicationClient{} + client.On("GetChangeRevision", mock.Anything, mock.Anything).Return(&appclient.ChangeRevisionResponse{ + Revision: ptr.To("new-revision"), + }, nil) + + logger, logHook := test2.NewNullLogger() + + acrService := newTestACRService(client) + acrService.logger = logger + + app := createTestApp(syncedAppWithHistory) + + err := acrService.ChangeRevision(context.TODO(), app) + require.NoError(t, err) + + app, err = acrService.applicationClientset.ArgoprojV1alpha1().Applications(app.Namespace).Get(context.TODO(), app.Name, metav1.GetOptions{}) + require.NoError(t, err) + + assert.Equal(t, "new-revision", app.Status.OperationState.Operation.Sync.ChangeRevision) + + err = acrService.ChangeRevision(context.TODO(), app) + + require.NoError(t, err) + + lastLogEntry := logHook.LastEntry() + if lastLogEntry == nil { + t.Fatal("No log entry") + } + + require.Equal(t, "Change revision already calculated for application guestbook", lastLogEntry.Message) + }) +} diff --git a/argocd-cosign.pub b/argocd-cosign.pub new file mode 100644 index 0000000000000..bd14342b9c1b4 --- /dev/null +++ b/argocd-cosign.pub @@ -0,0 +1,4 @@ +-----BEGIN PUBLIC KEY----- +MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEesHEB7vX5Y2RxXypjMy1nI1z7iRG +JI9/gt/sYqzpsa65aaNP4npM43DDxoIy/MQBo9s/mxGxmA+8UXeDpVC9vw== +-----END PUBLIC KEY----- diff --git a/assets/swagger.json b/assets/swagger.json index 9436a6a6f4c08..78f0c1cb96acf 100644 --- a/assets/swagger.json +++ b/assets/swagger.json @@ -218,6 +218,83 @@ } } }, + "/api/v1/application-validate": { + "post": { + "tags": [ + "ApplicationService" + ], + "summary": "Create creates an application", + "operationId": "ApplicationService_ValidateSrcAndDst", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1alpha1Application" + } + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/applicationApplicationValidateResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/runtimeError" + } + } + } + } + }, + "/api/v1/application/changeRevision": { + "get": { + "tags": [ + "ApplicationService" + ], + "operationId": "ApplicationService_GetChangeRevision", + "parameters": [ + { + "type": "string", + "name": "appName", + "in": "query" + }, + { + "type": "string", + "name": "namespace", + "in": "query" + }, + { + "type": "string", + "name": "currentRevision", + "in": "query" + }, + { + "type": "string", + "name": "previousRevision", + "in": "query" + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/applicationChangeRevisionResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/runtimeError" + } + } + } + } + }, "/api/v1/applications": { "get": { "tags": [ @@ -1768,6 +1845,45 @@ } } }, + "/api/v1/applications/{name}/rollout-rollback": { + "post": { + "tags": [ + "ApplicationService" + ], + "summary": "Rollback application rollout", + "operationId": "ApplicationService_RollbackApplicationRollout", + "parameters": [ + { + "type": "string", + "name": "name", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/applicationApplicationRolloutRollbackRequest" + } + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/applicationApplicationRolloutRollbackResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/runtimeError" + } + } + } + } + }, "/api/v1/applications/{name}/spec": { "put": { "tags": [ @@ -4826,6 +4942,39 @@ } } }, + "applicationApplicationRolloutRollbackRequest": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "namespace": { + "type": "string" + }, + "rolloutName": { + "type": "string" + }, + "rolloutNamespace": { + "type": "string" + }, + "rolloutRevision": { + "type": "integer", + "format": "int64" + } + } + }, + "applicationApplicationRolloutRollbackResponse": { + "type": "object", + "properties": { + "newRevision": { + "type": "integer", + "format": "int64" + }, + "rollout": { + "type": "string" + } + } + }, "applicationApplicationSyncRequest": { "type": "object", "title": "ApplicationSyncRequest is a request to apply the config state to live state", @@ -4927,6 +5076,25 @@ } } }, + "applicationApplicationValidateResponse": { + "type": "object", + "properties": { + "entity": { + "type": "string" + }, + "error": { + "type": "string" + } + } + }, + "applicationChangeRevisionResponse": { + "type": "object", + "properties": { + "revision": { + "type": "string" + } + } + }, "applicationFileChunk": { "type": "object", "properties": { @@ -5578,6 +5746,35 @@ } } }, + "repositoryApplicationVersions": { + "type": "object", + "properties": { + "appVersion": { + "type": "string", + "title": "Application version presented by single value" + }, + "dependencies": { + "$ref": "#/definitions/repositoryDependencies" + } + } + }, + "repositoryDependencies": { + "type": "object", + "properties": { + "deps": { + "type": "string", + "title": "Content of Cart.yaml/dependencies" + }, + "lock": { + "type": "string", + "title": "Content of Chart.lock" + }, + "requirements": { + "type": "string", + "title": "Content of requirements.yaml" + } + } + }, "repositoryDirectoryAppSpec": { "type": "object", "title": "DirectoryAppSpec contains directory" @@ -5653,9 +5850,34 @@ } } }, + "repositoryManifest": { + "type": "object", + "properties": { + "compiledManifest": { + "type": "string", + "title": "The processed manifest that needs to be applied to the cluster" + }, + "line": { + "type": "integer", + "format": "int32", + "title": "The line in the file where the object starts" + }, + "path": { + "type": "string", + "title": "The path of the raw manifest inside the repo" + }, + "rawManifest": { + "description": "The pre-processed manifest (for example the kustomization.yaml\nwhen using kustmize or the values.yaml when using helm).", + "type": "string" + } + } + }, "repositoryManifestResponse": { "type": "object", "properties": { + "applicationVersions": { + "$ref": "#/definitions/repositoryApplicationVersions" + }, "commands": { "type": "array", "title": "Commands is the list of commands used to hydrate the manifests", @@ -5663,10 +5885,19 @@ "type": "string" } }, + "commitAuthor": { + "type": "string" + }, + "commitDate": { + "$ref": "#/definitions/v1Time" + }, + "commitMessage": { + "type": "string" + }, "manifests": { "type": "array", "items": { - "type": "string" + "$ref": "#/definitions/repositoryManifest" } }, "namespace": { @@ -5682,6 +5913,14 @@ "sourceType": { "type": "string" }, + "sourcesManifestsStartingIdx": { + "type": "array", + "title": "for multisourced apps will be [0,12,20], so this means that 0-11 - from first app source, 12-19 from second one, 20-x - third one", + "items": { + "type": "integer", + "format": "int32" + } + }, "verifyResult": { "type": "string", "title": "Raw response of git verify-commit operation (always the empty string for Helm)" @@ -8300,6 +8539,9 @@ "buildOptions": { "type": "string", "title": "BuildOptions is a string of build parameters to use when calling `kustomize build`" + }, + "setNamespace": { + "type": "boolean" } } }, @@ -9285,6 +9527,13 @@ "type": "object", "title": "ResourceNode contains information about live resource and its children\nTODO: describe members of this type", "properties": { + "annotations": { + "type": "object", + "title": "available for managed resource without k8s-last-applied-configuration", + "additionalProperties": { + "type": "string" + } + }, "createdAt": { "$ref": "#/definitions/v1Time" }, @@ -9303,6 +9552,13 @@ "$ref": "#/definitions/v1alpha1InfoItem" } }, + "labels": { + "type": "object", + "title": "available for managed resource", + "additionalProperties": { + "type": "string" + } + }, "networkingInfo": { "$ref": "#/definitions/v1alpha1ResourceNetworkingInfo" }, diff --git a/changelog/CHANGELOG-2.10-2024.3.26-681ab3018.md b/changelog/CHANGELOG-2.10-2024.3.26-681ab3018.md new file mode 100644 index 0000000000000..4f07af3102a9e --- /dev/null +++ b/changelog/CHANGELOG-2.10-2024.3.26-681ab3018.md @@ -0,0 +1,2 @@ +### Features +- feat: argo cd updated to 2.10.3 \ No newline at end of file diff --git a/changelog/CHANGELOG-2.10-2024.3.28-13182e5b3.md b/changelog/CHANGELOG-2.10-2024.3.28-13182e5b3.md new file mode 100644 index 0000000000000..fb4526adb4050 --- /dev/null +++ b/changelog/CHANGELOG-2.10-2024.3.28-13182e5b3.md @@ -0,0 +1,2 @@ +### Features +- feat(event-reporter): rename event-reporter metrics and move droppedEventsCounter as dedicated metric \ No newline at end of file diff --git a/changelog/CHANGELOG-2.10-2024.3.29-1dcc54e29.md b/changelog/CHANGELOG-2.10-2024.3.29-1dcc54e29.md new file mode 100644 index 0000000000000..af52226c2d4eb --- /dev/null +++ b/changelog/CHANGELOG-2.10-2024.3.29-1dcc54e29.md @@ -0,0 +1,2 @@ +### Features +1. Vuln: fixed critical issue: stdlib: bump ubuntu to 23.10 \ No newline at end of file diff --git a/changelog/CHANGELOG-2.10-2024.3.29-8acbc5d5f.md b/changelog/CHANGELOG-2.10-2024.3.29-8acbc5d5f.md new file mode 100644 index 0000000000000..2995dc3ec99bf --- /dev/null +++ b/changelog/CHANGELOG-2.10-2024.3.29-8acbc5d5f.md @@ -0,0 +1,2 @@ +### Features +- fix: rename API query according to Codefresh API update \ No newline at end of file diff --git a/changelog/CHANGELOG-2.10-2024.4.21-78528ac3f.md b/changelog/CHANGELOG-2.10-2024.4.21-78528ac3f.md new file mode 100644 index 0000000000000..3030235849543 --- /dev/null +++ b/changelog/CHANGELOG-2.10-2024.4.21-78528ac3f.md @@ -0,0 +1,2 @@ +### Features +- feat(controller): use manifest generate path during comparison \ No newline at end of file diff --git a/changelog/CHANGELOG-2.10-2024.5.14-27c6d52d8.md b/changelog/CHANGELOG-2.10-2024.5.14-27c6d52d8.md new file mode 100644 index 0000000000000..ca0be86b664b5 --- /dev/null +++ b/changelog/CHANGELOG-2.10-2024.5.14-27c6d52d8.md @@ -0,0 +1,2 @@ +### Features +- feat: security updates GHSA-9m6p-x4h2-6frq, GHSA-jhwx-mhww-rgc3 \ No newline at end of file diff --git a/changelog/CHANGELOG-2.10-2024.5.14-9315e75e1.md b/changelog/CHANGELOG-2.10-2024.5.14-9315e75e1.md new file mode 100644 index 0000000000000..ca0be86b664b5 --- /dev/null +++ b/changelog/CHANGELOG-2.10-2024.5.14-9315e75e1.md @@ -0,0 +1,2 @@ +### Features +- feat: security updates GHSA-9m6p-x4h2-6frq, GHSA-jhwx-mhww-rgc3 \ No newline at end of file diff --git a/changelog/CHANGELOG-2.10-2024.6.17-77e06d0f6.md b/changelog/CHANGELOG-2.10-2024.6.17-77e06d0f6.md new file mode 100644 index 0000000000000..e6b1155af826e --- /dev/null +++ b/changelog/CHANGELOG-2.10-2024.6.17-77e06d0f6.md @@ -0,0 +1,2 @@ +### Features +- feat: ability to provide codefresh CA certificate or use insecure mode (v2 event-reporter) \ No newline at end of file diff --git a/changelog/CHANGELOG-2.11-2024.6.18-a171b066e.md b/changelog/CHANGELOG-2.11-2024.6.18-a171b066e.md new file mode 100644 index 0000000000000..ce12fa9062c34 --- /dev/null +++ b/changelog/CHANGELOG-2.11-2024.6.18-a171b066e.md @@ -0,0 +1,2 @@ +### Features +- feat: update argo-cd to 2.11.3 \ No newline at end of file diff --git a/changelog/CHANGELOG-2.11-2024.6.26-5cebdff8d.md b/changelog/CHANGELOG-2.11-2024.6.26-5cebdff8d.md new file mode 100644 index 0000000000000..3281b5382e9f8 --- /dev/null +++ b/changelog/CHANGELOG-2.11-2024.6.26-5cebdff8d.md @@ -0,0 +1,2 @@ +### Fix +- fix(event-reporter v2): report event on application metadata changes \ No newline at end of file diff --git a/changelog/CHANGELOG-2.11-2024.7.2-c9bad168e.md b/changelog/CHANGELOG-2.11-2024.7.2-c9bad168e.md new file mode 100644 index 0000000000000..88d46c1fec888 --- /dev/null +++ b/changelog/CHANGELOG-2.11-2024.7.2-c9bad168e.md @@ -0,0 +1,2 @@ +### Fix +- fix(event-reporter v2): report application event from queue instead of requesting actual state again which potentially means doesn't get same data as in original event \ No newline at end of file diff --git a/changelog/CHANGELOG-2.11-2024.7.20-8eb51f7a6.md b/changelog/CHANGELOG-2.11-2024.7.20-8eb51f7a6.md new file mode 100644 index 0000000000000..623b92cc75ad0 --- /dev/null +++ b/changelog/CHANGELOG-2.11-2024.7.20-8eb51f7a6.md @@ -0,0 +1,2 @@ +### Fix +- fix event reporter base path for codefresh client \ No newline at end of file diff --git a/changelog/CHANGELOG-2.11-2024.7.3-c0941bcb4.md b/changelog/CHANGELOG-2.11-2024.7.3-c0941bcb4.md new file mode 100644 index 0000000000000..a7746265e6e32 --- /dev/null +++ b/changelog/CHANGELOG-2.11-2024.7.3-c0941bcb4.md @@ -0,0 +1,2 @@ +### Chore +- chore(event-reporter v2): code splitting, created utils package \ No newline at end of file diff --git a/changelog/CHANGELOG-2.11-2024.7.30-a31bf96bb.md b/changelog/CHANGELOG-2.11-2024.7.30-a31bf96bb.md new file mode 100644 index 0000000000000..3f2ce2a62f647 --- /dev/null +++ b/changelog/CHANGELOG-2.11-2024.7.30-a31bf96bb.md @@ -0,0 +1,2 @@ +### Chore +- fix: selfheal should work with monorepo \ No newline at end of file diff --git a/changelog/CHANGELOG-2.11-2024.7.30-fcda44e7b.md b/changelog/CHANGELOG-2.11-2024.7.30-fcda44e7b.md new file mode 100644 index 0000000000000..3f2ce2a62f647 --- /dev/null +++ b/changelog/CHANGELOG-2.11-2024.7.30-fcda44e7b.md @@ -0,0 +1,2 @@ +### Chore +- fix: selfheal should work with monorepo \ No newline at end of file diff --git a/changelog/CHANGELOG-2.11-2024.8.19-6be897266.md b/changelog/CHANGELOG-2.11-2024.8.19-6be897266.md new file mode 100644 index 0000000000000..ec07d1005bc37 --- /dev/null +++ b/changelog/CHANGELOG-2.11-2024.8.19-6be897266.md @@ -0,0 +1,2 @@ +### Chore +- chore: removed v1 reporter \ No newline at end of file diff --git a/changelog/CHANGELOG-2.11-2024.8.19-d20b4d9a7.md b/changelog/CHANGELOG-2.11-2024.8.19-d20b4d9a7.md new file mode 100644 index 0000000000000..47cb3a8281c7d --- /dev/null +++ b/changelog/CHANGELOG-2.11-2024.8.19-d20b4d9a7.md @@ -0,0 +1,2 @@ +### Chore +- chore: selfheal additional logs in CompareAppState \ No newline at end of file diff --git a/changelog/CHANGELOG-2.11-2024.8.27-53edaf2ef.md b/changelog/CHANGELOG-2.11-2024.8.27-53edaf2ef.md new file mode 100644 index 0000000000000..47cb3a8281c7d --- /dev/null +++ b/changelog/CHANGELOG-2.11-2024.8.27-53edaf2ef.md @@ -0,0 +1,2 @@ +### Chore +- chore: selfheal additional logs in CompareAppState \ No newline at end of file diff --git a/changelog/CHANGELOG-2.11-2024.8.27-7144356ed.md b/changelog/CHANGELOG-2.11-2024.8.27-7144356ed.md new file mode 100644 index 0000000000000..47cb3a8281c7d --- /dev/null +++ b/changelog/CHANGELOG-2.11-2024.8.27-7144356ed.md @@ -0,0 +1,2 @@ +### Chore +- chore: selfheal additional logs in CompareAppState \ No newline at end of file diff --git a/changelog/CHANGELOG-2.11-2024.8.28-62776e60e.md b/changelog/CHANGELOG-2.11-2024.8.28-62776e60e.md new file mode 100644 index 0000000000000..47cb3a8281c7d --- /dev/null +++ b/changelog/CHANGELOG-2.11-2024.8.28-62776e60e.md @@ -0,0 +1,2 @@ +### Chore +- chore: selfheal additional logs in CompareAppState \ No newline at end of file diff --git a/changelog/CHANGELOG-2.11-2024.8.29-fa0e3225a.md b/changelog/CHANGELOG-2.11-2024.8.29-fa0e3225a.md new file mode 100644 index 0000000000000..74d4934457254 --- /dev/null +++ b/changelog/CHANGELOG-2.11-2024.8.29-fa0e3225a.md @@ -0,0 +1,2 @@ +### Chore +- chore: selfheal bring back revision cache \ No newline at end of file diff --git a/changelog/CHANGELOG-2.11-2024.8.7-10260b1bc.md b/changelog/CHANGELOG-2.11-2024.8.7-10260b1bc.md new file mode 100644 index 0000000000000..3f2ce2a62f647 --- /dev/null +++ b/changelog/CHANGELOG-2.11-2024.8.7-10260b1bc.md @@ -0,0 +1,2 @@ +### Chore +- fix: selfheal should work with monorepo \ No newline at end of file diff --git a/changelog/CHANGELOG-2.11-2024.8.7-b088681c7.md b/changelog/CHANGELOG-2.11-2024.8.7-b088681c7.md new file mode 100644 index 0000000000000..3f2ce2a62f647 --- /dev/null +++ b/changelog/CHANGELOG-2.11-2024.8.7-b088681c7.md @@ -0,0 +1,2 @@ +### Chore +- fix: selfheal should work with monorepo \ No newline at end of file diff --git a/changelog/CHANGELOG-2.11-2024.8.8-0c809966a.md b/changelog/CHANGELOG-2.11-2024.8.8-0c809966a.md new file mode 100644 index 0000000000000..ebc2a9bf740e4 --- /dev/null +++ b/changelog/CHANGELOG-2.11-2024.8.8-0c809966a.md @@ -0,0 +1,2 @@ +### Chore +- chore: selfheal should work with monorepo \ No newline at end of file diff --git a/changelog/CHANGELOG-2.11-2024.8.8-9011506bf.md b/changelog/CHANGELOG-2.11-2024.8.8-9011506bf.md new file mode 100644 index 0000000000000..69a0c0c996d13 --- /dev/null +++ b/changelog/CHANGELOG-2.11-2024.8.8-9011506bf.md @@ -0,0 +1,2 @@ +### Chore +- chore: selfheal should work with monorepo additional, fix revision persistance \ No newline at end of file diff --git a/changelog/CHANGELOG-2.11-2024.8.8-f3821b5f9.md b/changelog/CHANGELOG-2.11-2024.8.8-f3821b5f9.md new file mode 100644 index 0000000000000..44f728a89a47b --- /dev/null +++ b/changelog/CHANGELOG-2.11-2024.8.8-f3821b5f9.md @@ -0,0 +1,2 @@ +### Chore +- chore: selfheal should work with monorepo additional logs \ No newline at end of file diff --git a/changelog/CHANGELOG-2.11-2024.9.18-45633bcd2.md b/changelog/CHANGELOG-2.11-2024.9.18-45633bcd2.md new file mode 100644 index 0000000000000..47cb3a8281c7d --- /dev/null +++ b/changelog/CHANGELOG-2.11-2024.9.18-45633bcd2.md @@ -0,0 +1,2 @@ +### Chore +- chore: selfheal additional logs in CompareAppState \ No newline at end of file diff --git a/changelog/CHANGELOG-2.12-2024.10.11-4a252db7c.md b/changelog/CHANGELOG-2.12-2024.10.11-4a252db7c.md new file mode 100644 index 0000000000000..ec837707a338b --- /dev/null +++ b/changelog/CHANGELOG-2.12-2024.10.11-4a252db7c.md @@ -0,0 +1,4 @@ +### Features +- feat: argocd-repo-server: support for arrays in promotion versionSource +- feat: event-reporter: getting version based on synced revision +- feat: argocd-repo-server: suppress 'version not found' error message when version configuration is not provided \ No newline at end of file diff --git a/changelog/CHANGELOG-2.12-2024.10.16-ae9bb9622.md b/changelog/CHANGELOG-2.12-2024.10.16-ae9bb9622.md new file mode 100644 index 0000000000000..2a9e8ccd44212 --- /dev/null +++ b/changelog/CHANGELOG-2.12-2024.10.16-ae9bb9622.md @@ -0,0 +1,2 @@ +### Features +- feat: manage clusters via proxy \ No newline at end of file diff --git a/changelog/CHANGELOG-2.12-2024.10.17-36fb3f0d1.md b/changelog/CHANGELOG-2.12-2024.10.17-36fb3f0d1.md new file mode 100644 index 0000000000000..165e327c295ad --- /dev/null +++ b/changelog/CHANGELOG-2.12-2024.10.17-36fb3f0d1.md @@ -0,0 +1,2 @@ +### Features +- feat: take logic for monorepo selfheal fix from oss \ No newline at end of file diff --git a/changelog/CHANGELOG-2.12-2024.10.23-0c500acc9.md b/changelog/CHANGELOG-2.12-2024.10.23-0c500acc9.md new file mode 100644 index 0000000000000..c3b61b2746b0e --- /dev/null +++ b/changelog/CHANGELOG-2.12-2024.10.23-0c500acc9.md @@ -0,0 +1,2 @@ +### Features +- feat(event-reporter): added warning conditions reporting \ No newline at end of file diff --git a/changelog/CHANGELOG-2.12-2024.10.5-66e1e38fa.md b/changelog/CHANGELOG-2.12-2024.10.5-66e1e38fa.md new file mode 100644 index 0000000000000..e4fe910a101a9 --- /dev/null +++ b/changelog/CHANGELOG-2.12-2024.10.5-66e1e38fa.md @@ -0,0 +1,2 @@ +### Features +- feat: event-reporter: report change revisions metadata in app annotations \ No newline at end of file diff --git a/changelog/CHANGELOG-2.12-2024.9.23-0dc32342c.md b/changelog/CHANGELOG-2.12-2024.9.23-0dc32342c.md new file mode 100644 index 0000000000000..4d55728e17ee7 --- /dev/null +++ b/changelog/CHANGELOG-2.12-2024.9.23-0dc32342c.md @@ -0,0 +1,2 @@ +### Features +- feat: monorepo controller v1.0.0 \ No newline at end of file diff --git a/changelog/CHANGELOG-2.12-2024.9.3-6f8e0c7e2.md b/changelog/CHANGELOG-2.12-2024.9.3-6f8e0c7e2.md new file mode 100644 index 0000000000000..6264095a57cd7 --- /dev/null +++ b/changelog/CHANGELOG-2.12-2024.9.3-6f8e0c7e2.md @@ -0,0 +1,2 @@ +### Chore +- chore: argo-cd update to 2.12.3 \ No newline at end of file diff --git a/changelog/CHANGELOG-2.12-2024.9.30-995854136.md b/changelog/CHANGELOG-2.12-2024.9.30-995854136.md new file mode 100644 index 0000000000000..db818c0e9351f --- /dev/null +++ b/changelog/CHANGELOG-2.12-2024.9.30-995854136.md @@ -0,0 +1,2 @@ +### Features +- fix: change revision controller should verify that revision already exists \ No newline at end of file diff --git a/changelog/CHANGELOG-2.12-2024.9.30-a87492b22.md b/changelog/CHANGELOG-2.12-2024.9.30-a87492b22.md new file mode 100644 index 0000000000000..673b8ee59d7ae --- /dev/null +++ b/changelog/CHANGELOG-2.12-2024.9.30-a87492b22.md @@ -0,0 +1,3 @@ +### Features +- fix: acr controller should support latest revision sync +- sec: upgrade helm to 3.15.4 in order to fix vulnerability \ No newline at end of file diff --git a/changelog/CHANGELOG-2.12-2024.9.9-ba613c5bd.md b/changelog/CHANGELOG-2.12-2024.9.9-ba613c5bd.md new file mode 100644 index 0000000000000..97ce74e0e4f8d --- /dev/null +++ b/changelog/CHANGELOG-2.12-2024.9.9-ba613c5bd.md @@ -0,0 +1,2 @@ +### Features +- feat: event-reporter: report resource health status errors with application event \ No newline at end of file diff --git a/changelog/CHANGELOG-2.12.3-2024.10.24-01773faa9.md b/changelog/CHANGELOG-2.12.3-2024.10.24-01773faa9.md new file mode 100644 index 0000000000000..c3e50097c2c79 --- /dev/null +++ b/changelog/CHANGELOG-2.12.3-2024.10.24-01773faa9.md @@ -0,0 +1,2 @@ +### Features +- chore: new release lifecycle \ No newline at end of file diff --git a/changelog/CHANGELOG-2.12.3-2024.10.24-17b898fc3.md b/changelog/CHANGELOG-2.12.3-2024.10.24-17b898fc3.md new file mode 100644 index 0000000000000..c3e50097c2c79 --- /dev/null +++ b/changelog/CHANGELOG-2.12.3-2024.10.24-17b898fc3.md @@ -0,0 +1,2 @@ +### Features +- chore: new release lifecycle \ No newline at end of file diff --git a/changelog/CHANGELOG-2.12.3-2024.10.24-2818781ba.md b/changelog/CHANGELOG-2.12.3-2024.10.24-2818781ba.md new file mode 100644 index 0000000000000..c3e50097c2c79 --- /dev/null +++ b/changelog/CHANGELOG-2.12.3-2024.10.24-2818781ba.md @@ -0,0 +1,2 @@ +### Features +- chore: new release lifecycle \ No newline at end of file diff --git a/changelog/CHANGELOG-2.12.3-2024.10.24-4245c5379.md b/changelog/CHANGELOG-2.12.3-2024.10.24-4245c5379.md new file mode 100644 index 0000000000000..c3e50097c2c79 --- /dev/null +++ b/changelog/CHANGELOG-2.12.3-2024.10.24-4245c5379.md @@ -0,0 +1,2 @@ +### Features +- chore: new release lifecycle \ No newline at end of file diff --git a/changelog/CHANGELOG-2.12.3-2024.10.24-477675894.md b/changelog/CHANGELOG-2.12.3-2024.10.24-477675894.md new file mode 100644 index 0000000000000..c3e50097c2c79 --- /dev/null +++ b/changelog/CHANGELOG-2.12.3-2024.10.24-477675894.md @@ -0,0 +1,2 @@ +### Features +- chore: new release lifecycle \ No newline at end of file diff --git a/changelog/CHANGELOG-2.12.3-2024.10.24-5204e2b0e.md b/changelog/CHANGELOG-2.12.3-2024.10.24-5204e2b0e.md new file mode 100644 index 0000000000000..c3e50097c2c79 --- /dev/null +++ b/changelog/CHANGELOG-2.12.3-2024.10.24-5204e2b0e.md @@ -0,0 +1,2 @@ +### Features +- chore: new release lifecycle \ No newline at end of file diff --git a/changelog/CHANGELOG-2.12.3-2024.10.24-531413858.md b/changelog/CHANGELOG-2.12.3-2024.10.24-531413858.md new file mode 100644 index 0000000000000..c3e50097c2c79 --- /dev/null +++ b/changelog/CHANGELOG-2.12.3-2024.10.24-531413858.md @@ -0,0 +1,2 @@ +### Features +- chore: new release lifecycle \ No newline at end of file diff --git a/changelog/CHANGELOG-2.12.3-2024.10.24-7419c42e2.md b/changelog/CHANGELOG-2.12.3-2024.10.24-7419c42e2.md new file mode 100644 index 0000000000000..c3e50097c2c79 --- /dev/null +++ b/changelog/CHANGELOG-2.12.3-2024.10.24-7419c42e2.md @@ -0,0 +1,2 @@ +### Features +- chore: new release lifecycle \ No newline at end of file diff --git a/changelog/CHANGELOG-2.12.3-2024.10.24-a9323b2b4.md b/changelog/CHANGELOG-2.12.3-2024.10.24-a9323b2b4.md new file mode 100644 index 0000000000000..c3e50097c2c79 --- /dev/null +++ b/changelog/CHANGELOG-2.12.3-2024.10.24-a9323b2b4.md @@ -0,0 +1,2 @@ +### Features +- chore: new release lifecycle \ No newline at end of file diff --git a/changelog/CHANGELOG-2.12.3-2024.10.24-ac70e7594.md b/changelog/CHANGELOG-2.12.3-2024.10.24-ac70e7594.md new file mode 100644 index 0000000000000..c3e50097c2c79 --- /dev/null +++ b/changelog/CHANGELOG-2.12.3-2024.10.24-ac70e7594.md @@ -0,0 +1,2 @@ +### Features +- chore: new release lifecycle \ No newline at end of file diff --git a/changelog/CHANGELOG-2.12.3-2024.10.24-bad5d67c0.md b/changelog/CHANGELOG-2.12.3-2024.10.24-bad5d67c0.md new file mode 100644 index 0000000000000..c3e50097c2c79 --- /dev/null +++ b/changelog/CHANGELOG-2.12.3-2024.10.24-bad5d67c0.md @@ -0,0 +1,2 @@ +### Features +- chore: new release lifecycle \ No newline at end of file diff --git a/changelog/CHANGELOG-2.12.3-2024.10.24-d2f4245b5.md b/changelog/CHANGELOG-2.12.3-2024.10.24-d2f4245b5.md new file mode 100644 index 0000000000000..c3e50097c2c79 --- /dev/null +++ b/changelog/CHANGELOG-2.12.3-2024.10.24-d2f4245b5.md @@ -0,0 +1,2 @@ +### Features +- chore: new release lifecycle \ No newline at end of file diff --git a/changelog/CHANGELOG-2.12.3-2024.10.24-f6464d0db.md b/changelog/CHANGELOG-2.12.3-2024.10.24-f6464d0db.md new file mode 100644 index 0000000000000..c3e50097c2c79 --- /dev/null +++ b/changelog/CHANGELOG-2.12.3-2024.10.24-f6464d0db.md @@ -0,0 +1,2 @@ +### Features +- chore: new release lifecycle \ No newline at end of file diff --git a/changelog/CHANGELOG-2.12.3-2024.10.28-20100fc54.md b/changelog/CHANGELOG-2.12.3-2024.10.28-20100fc54.md new file mode 100644 index 0000000000000..ac73e1b0295b1 --- /dev/null +++ b/changelog/CHANGELOG-2.12.3-2024.10.28-20100fc54.md @@ -0,0 +1,2 @@ +### Fixed +- fix: failures in update revision for path should not affect sync \ No newline at end of file diff --git a/changelog/CHANGELOG-2.12.3-2024.11.14-d7a4c4e7e.md b/changelog/CHANGELOG-2.12.3-2024.11.14-d7a4c4e7e.md new file mode 100644 index 0000000000000..c1666e82a2cba --- /dev/null +++ b/changelog/CHANGELOG-2.12.3-2024.11.14-d7a4c4e7e.md @@ -0,0 +1,3 @@ +### Changes +- fix(event-reporter): fixed issue when if managed resource in degraded state and all of it child nodes in non-degraded state no error reported +- fix(repo-server): fixed repeated resources generation for ApplicationSourceTypeDirectory \ No newline at end of file diff --git a/changelog/CHANGELOG-2.12.3-2024.12.17-4d75d35f4.md b/changelog/CHANGELOG-2.12.3-2024.12.17-4d75d35f4.md new file mode 100644 index 0000000000000..f26d54ef9a0d6 --- /dev/null +++ b/changelog/CHANGELOG-2.12.3-2024.12.17-4d75d35f4.md @@ -0,0 +1,2 @@ +### Features +- feat(event-reporter): multisourced apps support improvements: reporting syncOperationRevisions, detecting correct resource sourceIdx, reporting correct git commit info \ No newline at end of file diff --git a/changelog/CHANGELOG-2.12.3-2024.12.3-a26fd084e.md b/changelog/CHANGELOG-2.12.3-2024.12.3-a26fd084e.md new file mode 100644 index 0000000000000..f26d54ef9a0d6 --- /dev/null +++ b/changelog/CHANGELOG-2.12.3-2024.12.3-a26fd084e.md @@ -0,0 +1,2 @@ +### Features +- feat(event-reporter): multisourced apps support improvements: reporting syncOperationRevisions, detecting correct resource sourceIdx, reporting correct git commit info \ No newline at end of file diff --git a/changelog/CHANGELOG-2.12.3-2024.12.4-08fee87f0.md b/changelog/CHANGELOG-2.12.3-2024.12.4-08fee87f0.md new file mode 100644 index 0000000000000..f26d54ef9a0d6 --- /dev/null +++ b/changelog/CHANGELOG-2.12.3-2024.12.4-08fee87f0.md @@ -0,0 +1,2 @@ +### Features +- feat(event-reporter): multisourced apps support improvements: reporting syncOperationRevisions, detecting correct resource sourceIdx, reporting correct git commit info \ No newline at end of file diff --git a/changelog/CHANGELOG-2.12.3-2024.12.4-0a01f4e4f.md b/changelog/CHANGELOG-2.12.3-2024.12.4-0a01f4e4f.md new file mode 100644 index 0000000000000..f26d54ef9a0d6 --- /dev/null +++ b/changelog/CHANGELOG-2.12.3-2024.12.4-0a01f4e4f.md @@ -0,0 +1,2 @@ +### Features +- feat(event-reporter): multisourced apps support improvements: reporting syncOperationRevisions, detecting correct resource sourceIdx, reporting correct git commit info \ No newline at end of file diff --git a/changelog/CHANGELOG-2.12.3-2024.12.4-73170ef3b.md b/changelog/CHANGELOG-2.12.3-2024.12.4-73170ef3b.md new file mode 100644 index 0000000000000..f26d54ef9a0d6 --- /dev/null +++ b/changelog/CHANGELOG-2.12.3-2024.12.4-73170ef3b.md @@ -0,0 +1,2 @@ +### Features +- feat(event-reporter): multisourced apps support improvements: reporting syncOperationRevisions, detecting correct resource sourceIdx, reporting correct git commit info \ No newline at end of file diff --git a/changelog/CHANGELOG-2.13.3-2025.1.14-ad612bea1.md b/changelog/CHANGELOG-2.13.3-2025.1.14-ad612bea1.md new file mode 100644 index 0000000000000..01acf816201b3 --- /dev/null +++ b/changelog/CHANGELOG-2.13.3-2025.1.14-ad612bea1.md @@ -0,0 +1,2 @@ +### Features +- feat(event-reporter): using sources-server for getting application version \ No newline at end of file diff --git a/changelog/CHANGELOG-2.13.3-2025.1.14-f019b07b9.md b/changelog/CHANGELOG-2.13.3-2025.1.14-f019b07b9.md new file mode 100644 index 0000000000000..bea00bb161dbc --- /dev/null +++ b/changelog/CHANGELOG-2.13.3-2025.1.14-f019b07b9.md @@ -0,0 +1,2 @@ +### Features +- chore(argo-cd): upgraded core to argo-cd OSS (2.13.3) \ No newline at end of file diff --git a/changelog/CHANGELOG-2.13.3-2025.1.15-9f3c74c06.md b/changelog/CHANGELOG-2.13.3-2025.1.15-9f3c74c06.md new file mode 100644 index 0000000000000..01acf816201b3 --- /dev/null +++ b/changelog/CHANGELOG-2.13.3-2025.1.15-9f3c74c06.md @@ -0,0 +1,2 @@ +### Features +- feat(event-reporter): using sources-server for getting application version \ No newline at end of file diff --git a/changelog/CHANGELOG-2.13.3-2025.1.16-39ce1d3d0.md b/changelog/CHANGELOG-2.13.3-2025.1.16-39ce1d3d0.md new file mode 100644 index 0000000000000..c0af80854db49 --- /dev/null +++ b/changelog/CHANGELOG-2.13.3-2025.1.16-39ce1d3d0.md @@ -0,0 +1,2 @@ +### Features +- feat(event-reporter): allow git integration ConfigMap reporting \ No newline at end of file diff --git a/changelog/CHANGELOG-2.13.3-2025.1.9-67d01f9e0.md b/changelog/CHANGELOG-2.13.3-2025.1.9-67d01f9e0.md new file mode 100644 index 0000000000000..bea00bb161dbc --- /dev/null +++ b/changelog/CHANGELOG-2.13.3-2025.1.9-67d01f9e0.md @@ -0,0 +1,2 @@ +### Features +- chore(argo-cd): upgraded core to argo-cd OSS (2.13.3) \ No newline at end of file diff --git a/changelog/CHANGELOG-2.13.3-2025.2.12-206ee2626.md b/changelog/CHANGELOG-2.13.3-2025.2.12-206ee2626.md new file mode 100644 index 0000000000000..c0af80854db49 --- /dev/null +++ b/changelog/CHANGELOG-2.13.3-2025.2.12-206ee2626.md @@ -0,0 +1,2 @@ +### Features +- feat(event-reporter): allow git integration ConfigMap reporting \ No newline at end of file diff --git a/changelog/CHANGELOG-2.13.3-2025.2.12-74ef6f192.md b/changelog/CHANGELOG-2.13.3-2025.2.12-74ef6f192.md new file mode 100644 index 0000000000000..a212fb9513c92 --- /dev/null +++ b/changelog/CHANGELOG-2.13.3-2025.2.12-74ef6f192.md @@ -0,0 +1,3 @@ +### Features +- fix(argo-cd): bumped go-git to 5.13.1 +- fix(release): bumped GitHub actions upload-artifact to v4.4.0 in binaries job \ No newline at end of file diff --git a/changelog/CHANGELOG-2.13.3-2025.2.12-7bfd6c858.md b/changelog/CHANGELOG-2.13.3-2025.2.12-7bfd6c858.md new file mode 100644 index 0000000000000..4b52a20a1cab1 --- /dev/null +++ b/changelog/CHANGELOG-2.13.3-2025.2.12-7bfd6c858.md @@ -0,0 +1,2 @@ +### Features +- fix(release): bumped GitHub actions download-artifact to v4.1.8 in generate sbom job \ No newline at end of file diff --git a/changelog/CHANGELOG-2.13.3-2025.3.3-bddbd99f7.md b/changelog/CHANGELOG-2.13.3-2025.3.3-bddbd99f7.md new file mode 100644 index 0000000000000..4a588fc8eb5fa --- /dev/null +++ b/changelog/CHANGELOG-2.13.3-2025.3.3-bddbd99f7.md @@ -0,0 +1,5 @@ +### Features +- fix(ci): removed null security context from redis-ha values.yaml to placate helm 3.17.1 +- feat: bumped helm to 3.17.1 +- feat: bumped golang-jwt/jwt/v4 to 4.5.1 +- feat: bumped GitHub actions/cache to 4.2.0 \ No newline at end of file diff --git a/changelog/CHANGELOG-2.13.3-2025.3.5-50344f005.md b/changelog/CHANGELOG-2.13.3-2025.3.5-50344f005.md new file mode 100644 index 0000000000000..8d673939056b9 --- /dev/null +++ b/changelog/CHANGELOG-2.13.3-2025.3.5-50344f005.md @@ -0,0 +1,2 @@ +### Features +- feat: upgraded git-lfs to 3.6.1 \ No newline at end of file diff --git a/changelog/CHANGELOG-2.8-2023.12.06-da4f96e57.md b/changelog/CHANGELOG-2.8-2023.12.06-da4f96e57.md new file mode 100644 index 0000000000000..cca8c982f1be8 --- /dev/null +++ b/changelog/CHANGELOG-2.8-2023.12.06-da4f96e57.md @@ -0,0 +1,8 @@ +### Bug fixes +- feat: support application level extensions (#9923) +- feat: support multiple extensions per resource group/kind (#9834) +- fix: extensions is not loading for ConfigMap/Pods (#10010) +- fix: upgrade moment from 2.29.2 to 2.29.3 (#9330) +### Other changes +- chore: update parse-url (#10101) +- docs: add api field example in the appset security doc (#10087) \ No newline at end of file diff --git a/changelog/CHANGELOG-2.9-2023.12.07-26af024e0.md b/changelog/CHANGELOG-2.9-2023.12.07-26af024e0.md new file mode 100644 index 0000000000000..8fb0899af71f7 --- /dev/null +++ b/changelog/CHANGELOG-2.9-2023.12.07-26af024e0.md @@ -0,0 +1 @@ +some important feature \ No newline at end of file diff --git a/changelog/CHANGELOG-2.9-2023.12.22-f5398c630.md b/changelog/CHANGELOG-2.9-2023.12.22-f5398c630.md new file mode 100644 index 0000000000000..2f10767b12344 --- /dev/null +++ b/changelog/CHANGELOG-2.9-2023.12.22-f5398c630.md @@ -0,0 +1,2 @@ +### Bug fixes +- fix: application event should be reported when application destination is incorrect \ No newline at end of file diff --git a/changelog/CHANGELOG-2.9-2023.12.26-47086b8e8.md b/changelog/CHANGELOG-2.9-2023.12.26-47086b8e8.md new file mode 100644 index 0000000000000..b39d42762242f --- /dev/null +++ b/changelog/CHANGELOG-2.9-2023.12.26-47086b8e8.md @@ -0,0 +1,2 @@ +### Features +- feat: application event reporter support http communication between event reporter and argocd \ No newline at end of file diff --git a/changelog/CHANGELOG-2.9-2023.12.28-a52e719a5.md b/changelog/CHANGELOG-2.9-2023.12.28-a52e719a5.md new file mode 100644 index 0000000000000..71595df167b77 --- /dev/null +++ b/changelog/CHANGELOG-2.9-2023.12.28-a52e719a5.md @@ -0,0 +1,4 @@ +### Event reporter v2.0.2 + +* Feat: added new metric cf_e_reporter_app_events_size and new bool env var EVENT_REPORTER_DETAILED_METRICS, if false will report 'not_reported' label values +* Feat: added support for argocd path to event reporter and new env var ARGOCD_SERVER_ROOTPATH \ No newline at end of file diff --git a/changelog/CHANGELOG-2.9-2024.01.16-207f20c91.md b/changelog/CHANGELOG-2.9-2024.01.16-207f20c91.md new file mode 100644 index 0000000000000..071d854e9df08 --- /dev/null +++ b/changelog/CHANGELOG-2.9-2024.01.16-207f20c91.md @@ -0,0 +1,7 @@ +### Event reporter v2.0.2 + +* Fix: app events with manifest generation error (non-existed path, repo, project, etc.) not reported to codefresh + +### Argocd Server (built-in event-reporter) + +* Fix: app events with manifest generation error (non-existed path, repo, project, etc.) not reported to codefresh \ No newline at end of file diff --git a/changelog/CHANGELOG-2.9-2024.01.16-f663c785d.md b/changelog/CHANGELOG-2.9-2024.01.16-f663c785d.md new file mode 100644 index 0000000000000..bdc127ca8f794 --- /dev/null +++ b/changelog/CHANGELOG-2.9-2024.01.16-f663c785d.md @@ -0,0 +1,3 @@ +### Bugfixes +1. [event-reporter]: apps not in controller ns not reported. +2. [event-reporter]: source object payload doesn't include correct gitSourceNamespace if resource ns != application ns \ No newline at end of file diff --git a/changelog/CHANGELOG-2.9-2024.1.17-b48801c0d.md b/changelog/CHANGELOG-2.9-2024.1.17-b48801c0d.md new file mode 100644 index 0000000000000..cd33a58f215ff --- /dev/null +++ b/changelog/CHANGELOG-2.9-2024.1.17-b48801c0d.md @@ -0,0 +1,2 @@ +### Event reporter v2.0.3 +1. Implemented a fixed window rate limiter for the event reporter to prevent the application from overflowing the entire reporter queue. This enhancement ensures timely reporting without causing delays for other applications. \ No newline at end of file diff --git a/changelog/CHANGELOG-2.9-2024.1.17-fd6208b56.md b/changelog/CHANGELOG-2.9-2024.1.17-fd6208b56.md new file mode 100644 index 0000000000000..ea16fc0726b6c --- /dev/null +++ b/changelog/CHANGELOG-2.9-2024.1.17-fd6208b56.md @@ -0,0 +1,2 @@ +### Event reporter v2.0.4 +1. Support learning mode for event reporter. \ No newline at end of file diff --git a/changelog/CHANGELOG-2.9-2024.1.22-375d827f3.md b/changelog/CHANGELOG-2.9-2024.1.22-375d827f3.md new file mode 100644 index 0000000000000..3cffb236a3f42 --- /dev/null +++ b/changelog/CHANGELOG-2.9-2024.1.22-375d827f3.md @@ -0,0 +1,2 @@ +### Event reporter v2.0.4 +1. Bugfix: added support of project and appNamespace query params to httpApplicationClient to fix permission denied requests. \ No newline at end of file diff --git a/changelog/CHANGELOG-2.9-2024.1.24-ccd7124b3.md b/changelog/CHANGELOG-2.9-2024.1.24-ccd7124b3.md new file mode 100644 index 0000000000000..83bd087a8a9eb --- /dev/null +++ b/changelog/CHANGELOG-2.9-2024.1.24-ccd7124b3.md @@ -0,0 +1,3 @@ +### Event reporter v2.0.5 +1. Vuln: fixed critical issue: github.com/go-git/go-git/v5: v5.8.1 -> v5.11.0 +2. Vuln: fixed critical issue: stdlib: bump ubuntu to 23.10 \ No newline at end of file diff --git a/changelog/CHANGELOG-2.9-2024.2.14-58059e8b0.md b/changelog/CHANGELOG-2.9-2024.2.14-58059e8b0.md new file mode 100644 index 0000000000000..db04409929ba6 --- /dev/null +++ b/changelog/CHANGELOG-2.9-2024.2.14-58059e8b0.md @@ -0,0 +1,2 @@ +### Features +- feat: Use application metadata for Application config query \ No newline at end of file diff --git a/changelog/CHANGELOG-2.9-2024.2.14-76fb55f6f.md b/changelog/CHANGELOG-2.9-2024.2.14-76fb55f6f.md new file mode 100644 index 0000000000000..25a263a8bdbb9 --- /dev/null +++ b/changelog/CHANGELOG-2.9-2024.2.14-76fb55f6f.md @@ -0,0 +1,2 @@ +### Features +- feat: additional logs to controller that explains why resource is out of sync \ No newline at end of file diff --git a/changelog/CHANGELOG-2.9-2024.2.14-9beee4cca.md b/changelog/CHANGELOG-2.9-2024.2.14-9beee4cca.md new file mode 100644 index 0000000000000..25a263a8bdbb9 --- /dev/null +++ b/changelog/CHANGELOG-2.9-2024.2.14-9beee4cca.md @@ -0,0 +1,2 @@ +### Features +- feat: additional logs to controller that explains why resource is out of sync \ No newline at end of file diff --git a/changelog/CHANGELOG-2.9-2024.2.15-03fa32937.md b/changelog/CHANGELOG-2.9-2024.2.15-03fa32937.md new file mode 100644 index 0000000000000..25a263a8bdbb9 --- /dev/null +++ b/changelog/CHANGELOG-2.9-2024.2.15-03fa32937.md @@ -0,0 +1,2 @@ +### Features +- feat: additional logs to controller that explains why resource is out of sync \ No newline at end of file diff --git a/changelog/CHANGELOG-2.9-2024.2.15-4e53504b9.md b/changelog/CHANGELOG-2.9-2024.2.15-4e53504b9.md new file mode 100644 index 0000000000000..81135410db560 --- /dev/null +++ b/changelog/CHANGELOG-2.9-2024.2.15-4e53504b9.md @@ -0,0 +1,3 @@ +### Features +- feat: Don't report application versions when the CODEFRESH_APPLICATION_VERSIONING_ENABLED flag is disabled +- feat: Don't get application configuration when the CODEFRESH_USE_APPLICATION_CONFIGURATION flag is disabled \ No newline at end of file diff --git a/changelog/CHANGELOG-2.9-2024.2.15-cc783d89f.md b/changelog/CHANGELOG-2.9-2024.2.15-cc783d89f.md new file mode 100644 index 0000000000000..40804956e20ca --- /dev/null +++ b/changelog/CHANGELOG-2.9-2024.2.15-cc783d89f.md @@ -0,0 +1,2 @@ +Features +fix: rename codefresh variables \ No newline at end of file diff --git a/changelog/CHANGELOG-2.9-2024.2.15-d04e12c26.md b/changelog/CHANGELOG-2.9-2024.2.15-d04e12c26.md new file mode 100644 index 0000000000000..cd76209680b33 --- /dev/null +++ b/changelog/CHANGELOG-2.9-2024.2.15-d04e12c26.md @@ -0,0 +1,2 @@ +### Features +- fix: rename codefresh variable inside of repo-server and move them to avoid merge conflicts \ No newline at end of file diff --git a/changelog/CHANGELOG-2.9-2024.2.19-5d3b6792c.md b/changelog/CHANGELOG-2.9-2024.2.19-5d3b6792c.md new file mode 100644 index 0000000000000..9cd75e4ced626 --- /dev/null +++ b/changelog/CHANGELOG-2.9-2024.2.19-5d3b6792c.md @@ -0,0 +1,2 @@ +### Features +- fix: revert rate limited due to dependencies issues \ No newline at end of file diff --git a/changelog/CHANGELOG-2.9-2024.2.19-7f1e9b76a.md b/changelog/CHANGELOG-2.9-2024.2.19-7f1e9b76a.md new file mode 100644 index 0000000000000..5ae31eb65b85e --- /dev/null +++ b/changelog/CHANGELOG-2.9-2024.2.19-7f1e9b76a.md @@ -0,0 +1,2 @@ +### Features +- fix: revert 2.9-2024.2.4-fc84c8a9c due to cmp issue \ No newline at end of file diff --git a/changelog/CHANGELOG-2.9-2024.2.19-aabc4c16d.md b/changelog/CHANGELOG-2.9-2024.2.19-aabc4c16d.md new file mode 100644 index 0000000000000..5ae31eb65b85e --- /dev/null +++ b/changelog/CHANGELOG-2.9-2024.2.19-aabc4c16d.md @@ -0,0 +1,2 @@ +### Features +- fix: revert 2.9-2024.2.4-fc84c8a9c due to cmp issue \ No newline at end of file diff --git a/changelog/CHANGELOG-2.9-2024.2.19-f00382968.md b/changelog/CHANGELOG-2.9-2024.2.19-f00382968.md new file mode 100644 index 0000000000000..5ae31eb65b85e --- /dev/null +++ b/changelog/CHANGELOG-2.9-2024.2.19-f00382968.md @@ -0,0 +1,2 @@ +### Features +- fix: revert 2.9-2024.2.4-fc84c8a9c due to cmp issue \ No newline at end of file diff --git a/changelog/CHANGELOG-2.9-2024.2.20-0aa8aec53.md b/changelog/CHANGELOG-2.9-2024.2.20-0aa8aec53.md new file mode 100644 index 0000000000000..6a8d39b961e91 --- /dev/null +++ b/changelog/CHANGELOG-2.9-2024.2.20-0aa8aec53.md @@ -0,0 +1,2 @@ +### Features +- fix: revert version config changes due to cmp issue \ No newline at end of file diff --git a/changelog/CHANGELOG-2.9-2024.2.20-cb91bdef2.md b/changelog/CHANGELOG-2.9-2024.2.20-cb91bdef2.md new file mode 100644 index 0000000000000..6a8d39b961e91 --- /dev/null +++ b/changelog/CHANGELOG-2.9-2024.2.20-cb91bdef2.md @@ -0,0 +1,2 @@ +### Features +- fix: revert version config changes due to cmp issue \ No newline at end of file diff --git a/changelog/CHANGELOG-2.9-2024.2.28-2ca55aef7.md b/changelog/CHANGELOG-2.9-2024.2.28-2ca55aef7.md new file mode 100644 index 0000000000000..8084c06699ce0 --- /dev/null +++ b/changelog/CHANGELOG-2.9-2024.2.28-2ca55aef7.md @@ -0,0 +1,2 @@ +### Features +- feat(event-reporter): remove rate limiter due to issues with cmp plugin \ No newline at end of file diff --git a/changelog/CHANGELOG-2.9-2024.2.28-b6a7d8152.md b/changelog/CHANGELOG-2.9-2024.2.28-b6a7d8152.md new file mode 100644 index 0000000000000..8084c06699ce0 --- /dev/null +++ b/changelog/CHANGELOG-2.9-2024.2.28-b6a7d8152.md @@ -0,0 +1,2 @@ +### Features +- feat(event-reporter): remove rate limiter due to issues with cmp plugin \ No newline at end of file diff --git a/changelog/CHANGELOG-2.9-2024.2.28-d29aa3754.md b/changelog/CHANGELOG-2.9-2024.2.28-d29aa3754.md new file mode 100644 index 0000000000000..bc17bdc2aee67 --- /dev/null +++ b/changelog/CHANGELOG-2.9-2024.2.28-d29aa3754.md @@ -0,0 +1,2 @@ +### Features +- feat(controller): use manifest generate path during comparison \ No newline at end of file diff --git a/changelog/CHANGELOG-2.9-2024.2.29-0f82ce2ec.md b/changelog/CHANGELOG-2.9-2024.2.29-0f82ce2ec.md new file mode 100644 index 0000000000000..da8ac297613e6 --- /dev/null +++ b/changelog/CHANGELOG-2.9-2024.2.29-0f82ce2ec.md @@ -0,0 +1,2 @@ +### Features +- feat(event_reporter): report chart version as part of manifest for environment feature \ No newline at end of file diff --git a/changelog/CHANGELOG-2.9-2024.2.4-fc84c8a9c.md b/changelog/CHANGELOG-2.9-2024.2.4-fc84c8a9c.md new file mode 100644 index 0000000000000..5a9df6fc4c99f --- /dev/null +++ b/changelog/CHANGELOG-2.9-2024.2.4-fc84c8a9c.md @@ -0,0 +1,3 @@ +### Bug fixes + +- fix: application deletion is not being reported correctly to Codefresh platform (#280) diff --git a/changelog/CHANGELOG-2.9-2024.2.7-2d48b28f4.md b/changelog/CHANGELOG-2.9-2024.2.7-2d48b28f4.md new file mode 100644 index 0000000000000..fd91bb5edfd42 --- /dev/null +++ b/changelog/CHANGELOG-2.9-2024.2.7-2d48b28f4.md @@ -0,0 +1,2 @@ +### Features +- feat: getting VersionSource from ApplicationConfiguration resource. Version info can be read from yaml, yml or json files with jsonPath expression. The default location is `{.appVersion}` path of the `Chart.yaml` \ No newline at end of file diff --git a/changelog/CHANGELOG-2.9-2024.2.7-9d27fc1b8.md b/changelog/CHANGELOG-2.9-2024.2.7-9d27fc1b8.md new file mode 100644 index 0000000000000..f69608c99abbe --- /dev/null +++ b/changelog/CHANGELOG-2.9-2024.2.7-9d27fc1b8.md @@ -0,0 +1,2 @@ +### Features +- feat: Additional logs for application versions \ No newline at end of file diff --git a/changelog/CHANGELOG-2.9-2024.2.8-8ba4b03d4.md b/changelog/CHANGELOG-2.9-2024.2.8-8ba4b03d4.md new file mode 100644 index 0000000000000..3927ee4babd48 --- /dev/null +++ b/changelog/CHANGELOG-2.9-2024.2.8-8ba4b03d4.md @@ -0,0 +1,4 @@ +### Reverted prs + +- feat: Additional logs for application versions #279 + #283 +- vuln: Event reporter critical fixes #278 diff --git a/changelog/CHANGELOG-2.9-2024.2.9-2fd6a5c2a.md b/changelog/CHANGELOG-2.9-2024.2.9-2fd6a5c2a.md new file mode 100644 index 0000000000000..fd91bb5edfd42 --- /dev/null +++ b/changelog/CHANGELOG-2.9-2024.2.9-2fd6a5c2a.md @@ -0,0 +1,2 @@ +### Features +- feat: getting VersionSource from ApplicationConfiguration resource. Version info can be read from yaml, yml or json files with jsonPath expression. The default location is `{.appVersion}` path of the `Chart.yaml` \ No newline at end of file diff --git a/changelog/CHANGELOG-2.9-2024.3.12-b23aa3fb6.md b/changelog/CHANGELOG-2.9-2024.3.12-b23aa3fb6.md new file mode 100644 index 0000000000000..7a05455a97cf1 --- /dev/null +++ b/changelog/CHANGELOG-2.9-2024.3.12-b23aa3fb6.md @@ -0,0 +1,2 @@ +### Features +- feat: using $ format for jsonPath expressions \ No newline at end of file diff --git a/changelog/CHANGELOG-2.9-2024.3.14-6cca9ccf8.md b/changelog/CHANGELOG-2.9-2024.3.14-6cca9ccf8.md new file mode 100644 index 0000000000000..814f6eab4ca7c --- /dev/null +++ b/changelog/CHANGELOG-2.9-2024.3.14-6cca9ccf8.md @@ -0,0 +1,2 @@ +### Features +- fix: fix default version config \ No newline at end of file diff --git a/changelog/CHANGELOG-2.9-2024.3.5-80c3e7225.md b/changelog/CHANGELOG-2.9-2024.3.5-80c3e7225.md new file mode 100644 index 0000000000000..66d1a3661b43d --- /dev/null +++ b/changelog/CHANGELOG-2.9-2024.3.5-80c3e7225.md @@ -0,0 +1,2 @@ +### Features +- feat: implement rate limiter for event reporter \ No newline at end of file diff --git a/changelog/CHANGELOG.md b/changelog/CHANGELOG.md new file mode 100644 index 0000000000000..8d673939056b9 --- /dev/null +++ b/changelog/CHANGELOG.md @@ -0,0 +1,2 @@ +### Features +- feat: upgraded git-lfs to 3.6.1 \ No newline at end of file diff --git a/cmd/application-change-revision-controller/commands/application_change_revision_controller.go b/cmd/application-change-revision-controller/commands/application_change_revision_controller.go new file mode 100644 index 0000000000000..f635906f9d469 --- /dev/null +++ b/cmd/application-change-revision-controller/commands/application_change_revision_controller.go @@ -0,0 +1,158 @@ +package commands + +import ( + "context" + "fmt" + "time" + + acr "github.com/argoproj/argo-cd/v2/acr_controller" + cacheutil "github.com/argoproj/argo-cd/v2/util/cache" + + "github.com/argoproj/pkg/stats" + "github.com/redis/go-redis/v9" + log "github.com/sirupsen/logrus" + "github.com/spf13/cobra" + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/tools/clientcmd" + + appclient "github.com/argoproj/argo-cd/v2/acr_controller/application" + + cmdutil "github.com/argoproj/argo-cd/v2/cmd/util" + "github.com/argoproj/argo-cd/v2/common" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + appclientset "github.com/argoproj/argo-cd/v2/pkg/client/clientset/versioned" + servercache "github.com/argoproj/argo-cd/v2/server/cache" + "github.com/argoproj/argo-cd/v2/util/cli" + "github.com/argoproj/argo-cd/v2/util/env" + "github.com/argoproj/argo-cd/v2/util/errors" + "github.com/argoproj/argo-cd/v2/util/kube" +) + +const ( + failureRetryCountEnv = "EVENT_REPORTER_K8S_RETRY_COUNT" + failureRetryPeriodMilliSecondsEnv = "EVENT_REPORTE_K8S_RETRY_DURATION_MILLISECONDS" +) + +var ( + failureRetryCount = 0 + failureRetryPeriodMilliSeconds = 100 +) + +func init() { + failureRetryCount = env.ParseNumFromEnv(failureRetryCountEnv, failureRetryCount, 0, 10) + failureRetryPeriodMilliSeconds = env.ParseNumFromEnv(failureRetryPeriodMilliSecondsEnv, failureRetryPeriodMilliSeconds, 0, 1000) +} + +func getApplicationClient(address, token string, path string) appclient.ApplicationClient { + return appclient.NewHttpApplicationClient(token, address, path) +} + +// NewCommand returns a new instance of an application change revision command +func NewCommand() *cobra.Command { + var ( + redisClient *redis.Client + listenHost string + listenPort int + glogLevel int + clientConfig clientcmd.ClientConfig + applicationServerAddress string + cacheSrc func() (*servercache.Cache, error) + contentSecurityPolicy string + applicationNamespaces []string + argocdToken string + rootpath string + ) + command := &cobra.Command{ + Use: cliName, + Short: "Run the Change Revision Controller server", + Long: "The Change Revision Controller is a service that listens for application events and updates the application's revision in the application CRD", + DisableAutoGenTag: true, + Run: func(c *cobra.Command, args []string) { + ctx := c.Context() + + vers := common.GetVersion() + namespace, _, err := clientConfig.Namespace() + errors.CheckError(err) + vers.LogStartupInfo( + "Application Change Revision Controller", + map[string]any{ + "namespace": namespace, + "port": listenPort, + }, + ) + + cli.SetLogFormat(cmdutil.LogFormat) + cli.SetLogLevel(cmdutil.LogLevel) + cli.SetGLogLevel(glogLevel) + + config, err := clientConfig.ClientConfig() + errors.CheckError(err) + errors.CheckError(v1alpha1.SetK8SConfigDefaults(config)) + + cache, err := cacheSrc() + errors.CheckError(err) + + kubeclientset := kubernetes.NewForConfigOrDie(config) + + appclientsetConfig, err := clientConfig.ClientConfig() + errors.CheckError(err) + errors.CheckError(v1alpha1.SetK8SConfigDefaults(appclientsetConfig)) + config.UserAgent = fmt.Sprintf("argocd-server/%s (%s)", vers.Version, vers.Platform) + + if failureRetryCount > 0 { + appclientsetConfig = kube.AddFailureRetryWrapper(appclientsetConfig, failureRetryCount, failureRetryPeriodMilliSeconds) + } + appClientSet := appclientset.NewForConfigOrDie(appclientsetConfig) + + changeRevisionServerOpts := acr.ACRServerOpts{ + ListenPort: listenPort, + ListenHost: listenHost, + Namespace: namespace, + KubeClientset: kubeclientset, + AppClientset: appClientSet, + Cache: cache, + RedisClient: redisClient, + ApplicationNamespaces: applicationNamespaces, + ApplicationServiceClient: getApplicationClient(applicationServerAddress, argocdToken, rootpath), + } + + log.Info("Starting change revision controller server") + + stats.RegisterStackDumper() + stats.StartStatsTicker(10 * time.Minute) + stats.RegisterHeapDumper("memprofile") + changeRevisionServer := acr.NewApplicationChangeRevisionServer(ctx, changeRevisionServerOpts) + changeRevisionServer.Init(ctx) + lns, err := changeRevisionServer.Listen() + errors.CheckError(err) + for { + var closer func() + ctx, cancel := context.WithCancel(ctx) + changeRevisionServer.Run(ctx, lns) + cancel() + if closer != nil { + closer() + } + } + }, + } + + clientConfig = cli.AddKubectlFlagsToCmd(command) + command.Flags().StringVar(&rootpath, "argocd-server-path", env.StringFromEnv("ARGOCD_SERVER_ROOTPATH", ""), "Used if Argo CD is running behind reverse proxy under subpath different from /") + command.Flags().StringVar(&cmdutil.LogFormat, "logformat", env.StringFromEnv("ACR_CONTROLLER_LOGFORMAT", "text"), "Set the logging format. One of: text|json") + command.Flags().StringVar(&cmdutil.LogLevel, "loglevel", env.StringFromEnv("ACR_CONTROLLER_LOG_LEVEL", "info"), "Set the logging level. One of: debug|info|warn|error") + command.Flags().IntVar(&glogLevel, "gloglevel", 0, "Set the glog logging level") + command.Flags().StringVar(&applicationServerAddress, "application-server", env.StringFromEnv("ARGOCD_SERVER", common.DefaultApplicationServerAddr), "Application server address") + command.Flags().StringVar(&argocdToken, "argocd-token", env.StringFromEnv("ARGOCD_TOKEN", ""), "ArgoCD server JWT token") + command.AddCommand(cli.NewVersionCmd(cliName)) + command.Flags().StringVar(&listenHost, "address", env.StringFromEnv("ACR_CONTROLLER_LISTEN_ADDRESS", common.DefaultAddressACRController), "Listen on given address") + command.Flags().IntVar(&listenPort, "port", common.DefaultPortACRServer, "Listen on given port") + command.Flags().StringVar(&contentSecurityPolicy, "content-security-policy", env.StringFromEnv("ACR_CONTROLLER_CONTENT_SECURITY_POLICY", "frame-ancestors 'self';"), "Set Content-Security-Policy header in HTTP responses to `value`. To disable, set to \"\".") + command.Flags().StringSliceVar(&applicationNamespaces, "application-namespaces", env.StringsFromEnv("ARGOCD_APPLICATION_NAMESPACES", []string{}, ","), "List of additional namespaces where application resources can be managed in") + cacheSrc = servercache.AddCacheFlagsToCmd(command, cacheutil.Options{ + OnClientCreated: func(client *redis.Client) { + redisClient = client + }, + }) + return command +} diff --git a/cmd/application-change-revision-controller/commands/common.go b/cmd/application-change-revision-controller/commands/common.go new file mode 100644 index 0000000000000..c1ca08e656615 --- /dev/null +++ b/cmd/application-change-revision-controller/commands/common.go @@ -0,0 +1,6 @@ +package commands + +const ( + // cliName is the name of the CLI + cliName = "application-change-revision-controller" +) diff --git a/cmd/argocd-repo-server/commands/argocd_repo_server.go b/cmd/argocd-repo-server/commands/argocd_repo_server.go index 19d9a2a1e4b12..07a60447a7838 100644 --- a/cmd/argocd-repo-server/commands/argocd_repo_server.go +++ b/cmd/argocd-repo-server/commands/argocd_repo_server.go @@ -21,6 +21,7 @@ import ( cmdutil "github.com/argoproj/argo-cd/v2/cmd/util" "github.com/argoproj/argo-cd/v2/common" + "github.com/argoproj/argo-cd/v2/pkg/codefresh" "github.com/argoproj/argo-cd/v2/reposerver" "github.com/argoproj/argo-cd/v2/reposerver/apiclient" reposervercache "github.com/argoproj/argo-cd/v2/reposerver/cache" @@ -53,30 +54,34 @@ var ( func NewCommand() *cobra.Command { var ( - parallelismLimit int64 - listenPort int - listenHost string - metricsPort int - metricsHost string - otlpAddress string - otlpInsecure bool - otlpHeaders map[string]string - otlpAttrs []string - cacheSrc func() (*reposervercache.Cache, error) - tlsConfigCustomizer tls.ConfigCustomizer - tlsConfigCustomizerSrc func() (tls.ConfigCustomizer, error) - redisClient *redis.Client - disableTLS bool - maxCombinedDirectoryManifestsSize string - cmpTarExcludedGlobs []string - allowOutOfBoundsSymlinks bool - streamedManifestMaxTarSize string - streamedManifestMaxExtractedSize string - helmManifestMaxExtractedSize string - helmRegistryMaxIndexSize string - disableManifestMaxExtractedSize bool - includeHiddenDirectories bool - cmpUseManifestGeneratePaths bool + codefreshUrl string + codefreshToken string + codefreshApplicationVersioningEnabled bool + codefreshUseApplicationConfiguration bool + parallelismLimit int64 + listenPort int + listenHost string + metricsPort int + metricsHost string + otlpAddress string + otlpInsecure bool + otlpHeaders map[string]string + otlpAttrs []string + cacheSrc func() (*reposervercache.Cache, error) + tlsConfigCustomizer tls.ConfigCustomizer + tlsConfigCustomizerSrc func() (tls.ConfigCustomizer, error) + redisClient *redis.Client + disableTLS bool + maxCombinedDirectoryManifestsSize string + cmpTarExcludedGlobs []string + allowOutOfBoundsSymlinks bool + streamedManifestMaxTarSize string + streamedManifestMaxExtractedSize string + helmManifestMaxExtractedSize string + helmRegistryMaxIndexSize string + disableManifestMaxExtractedSize bool + includeHiddenDirectories bool + cmpUseManifestGeneratePaths bool ) command := cobra.Command{ Use: cliName, @@ -132,6 +137,12 @@ func NewCommand() *cobra.Command { metricsServer := metrics.NewMetricsServer() cacheutil.CollectMetrics(redisClient, metricsServer, nil) server, err := reposerver.NewServer(metricsServer, cache, tlsConfigCustomizer, repository.RepoServerInitConstants{ + CodefreshApplicationVersioningEnabled: codefreshApplicationVersioningEnabled, + CodefreshUseApplicationConfiguration: codefreshUseApplicationConfiguration, + CodefreshConfig: codefresh.CodefreshConfig{ + BaseURL: codefreshUrl, + AuthToken: codefreshToken, + }, ParallelismLimit: parallelismLimit, PauseGenerationAfterFailedGenerationAttempts: pauseGenerationAfterFailedGenerationAttempts, PauseGenerationOnFailureForMinutes: pauseGenerationOnFailureForMinutes, @@ -230,6 +241,12 @@ func NewCommand() *cobra.Command { return nil }, } + // *** CF specific variables *** + command.Flags().StringVar(&codefreshUrl, "codefresh-url", env.StringFromEnv("CODEFRESH_URL", "https://g.codefresh.io"), "Codefresh API URL") + command.Flags().StringVar(&codefreshToken, "codefresh-token", env.StringFromEnv("CODEFRESH_TOKEN", ""), "Codefresh token") + command.Flags().BoolVar(&codefreshApplicationVersioningEnabled, "codefresh-application-version-enabled", env.ParseBoolFromEnv("CODEFRESH_APPVERSION_ENABLED", true), "Allow Codefresh application versioning") + command.Flags().BoolVar(&codefreshUseApplicationConfiguration, "codefresh-application-version-use-appconfig", env.ParseBoolFromEnv("CODEFRESH_APPVERSION_USE_APPCONFIG", true), "Allow getting application configuration from the Codefresh API") + command.Flags().StringVar(&cmdutil.LogFormat, "logformat", env.StringFromEnv("ARGOCD_REPO_SERVER_LOGFORMAT", "text"), "Set the logging format. One of: text|json") command.Flags().StringVar(&cmdutil.LogLevel, "loglevel", env.StringFromEnv("ARGOCD_REPO_SERVER_LOGLEVEL", "info"), "Set the logging level. One of: debug|info|warn|error") command.Flags().Int64Var(¶llelismLimit, "parallelismlimit", int64(env.ParseNumFromEnv("ARGOCD_REPO_SERVER_PARALLELISM_LIMIT", 0, 0, math.MaxInt32)), "Limit on number of concurrent manifests generate requests. Any value less the 1 means no limit.") diff --git a/cmd/argocd/commands/admin/app_test.go b/cmd/argocd/commands/admin/app_test.go index 964d23ccab696..50ee4eb7e48ba 100644 --- a/cmd/argocd/commands/admin/app_test.go +++ b/cmd/argocd/commands/admin/app_test.go @@ -97,7 +97,11 @@ func TestGetReconcileResults_Refresh(t *testing.T) { clusterCache.On("GetGVKParser", mock.Anything).Return(nil) repoServerClient := mocks.RepoServerServiceClient{} repoServerClient.On("GenerateManifest", mock.Anything, mock.Anything).Return(&argocdclient.ManifestResponse{ - Manifests: []string{test.DeploymentManifest}, + Manifests: []*argocdclient.Manifest{ + { + CompiledManifest: test.DeploymentManifest, + }, + }, }, nil) repoServerClientset := mocks.Clientset{RepoServerServiceClient: &repoServerClient} liveStateCache := cachemocks.LiveStateCache{} diff --git a/cmd/argocd/commands/app.go b/cmd/argocd/commands/app.go index 3cfc5f13f1d9c..35e958f70ced8 100644 --- a/cmd/argocd/commands/app.go +++ b/cmd/argocd/commands/app.go @@ -1171,10 +1171,10 @@ func getLocalObjectsString(ctx context.Context, app *argoappv1.Application, proj ProjectName: proj.Name, ProjectSourceRepos: proj.Spec.SourceRepos, AnnotationManifestGeneratePaths: app.GetAnnotation(argoappv1.AnnotationKeyManifestGeneratePaths), - }, true, &git.NoopCredsStore{}, resource.MustParse("0"), nil) + }, true, &git.NoopCredsStore{}, resource.MustParse("0"), nil, nil) errors.CheckError(err) - return res.Manifests + return res.GetCompiledManifests() } type resourceInfoProvider struct { @@ -1388,7 +1388,7 @@ func findandPrintDiff(ctx context.Context, app *argoappv1.Application, proj *arg } else if diffOptions.revision != "" || len(diffOptions.revisions) > 0 { var unstructureds []*unstructured.Unstructured for _, mfst := range diffOptions.res.Manifests { - obj, err := argoappv1.UnmarshalToUnstructured(mfst) + obj, err := argoappv1.UnmarshalToUnstructured(mfst.CompiledManifest) errors.CheckError(err) unstructureds = append(unstructureds, obj) } @@ -1397,7 +1397,7 @@ func findandPrintDiff(ctx context.Context, app *argoappv1.Application, proj *arg } else if diffOptions.serversideRes != nil { var unstructureds []*unstructured.Unstructured for _, mfst := range diffOptions.serversideRes.Manifests { - obj, err := argoappv1.UnmarshalToUnstructured(mfst) + obj, err := argoappv1.UnmarshalToUnstructured(mfst.CompiledManifest) errors.CheckError(err) unstructureds = append(unstructureds, obj) } @@ -2091,7 +2091,7 @@ func NewApplicationSyncCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co fmt.Println("The name of the app is ", appName) for _, mfst := range res.Manifests { - obj, err := argoappv1.UnmarshalToUnstructured(mfst) + obj, err := argoappv1.UnmarshalToUnstructured(mfst.CompiledManifest) errors.CheckError(err) for key, selectedValue := range selectedLabels { if objectValue, ok := obj.GetLabels()[key]; ok && selectedValue == objectValue { @@ -3047,7 +3047,7 @@ func NewApplicationManifestsCommand(clientOpts *argocdclient.ClientOptions) *cob errors.CheckError(err) for _, mfst := range res.Manifests { - obj, err := argoappv1.UnmarshalToUnstructured(mfst) + obj, err := argoappv1.UnmarshalToUnstructured(mfst.CompiledManifest) errors.CheckError(err) unstructureds = append(unstructureds, obj) } @@ -3061,7 +3061,7 @@ func NewApplicationManifestsCommand(clientOpts *argocdclient.ClientOptions) *cob errors.CheckError(err) for _, mfst := range res.Manifests { - obj, err := argoappv1.UnmarshalToUnstructured(mfst) + obj, err := argoappv1.UnmarshalToUnstructured(mfst.CompiledManifest) errors.CheckError(err) unstructureds = append(unstructureds, obj) } diff --git a/cmd/argocd/commands/app_test.go b/cmd/argocd/commands/app_test.go index 57aede02a5b49..0b75deb84da94 100644 --- a/cmd/argocd/commands/app_test.go +++ b/cmd/argocd/commands/app_test.go @@ -2159,10 +2159,18 @@ func (c *fakeAppServiceClient) RunResourceAction(ctx context.Context, in *applic return nil, nil } +func (c *fakeAppServiceClient) RollbackApplicationRollout(context.Context, *applicationpkg.ApplicationRolloutRollbackRequest, ...grpc.CallOption) (*applicationpkg.ApplicationRolloutRollbackResponse, error) { + return nil, nil +} + func (c *fakeAppServiceClient) DeleteResource(ctx context.Context, in *applicationpkg.ApplicationResourceDeleteRequest, opts ...grpc.CallOption) (*applicationpkg.ApplicationResponse, error) { return nil, nil } +func (c *fakeAppServiceClient) ValidateSrcAndDst(ctx context.Context, in *applicationpkg.ApplicationValidationRequest, opts ...grpc.CallOption) (*applicationpkg.ApplicationValidateResponse, error) { + return nil, nil +} + func (c *fakeAppServiceClient) PodLogs(ctx context.Context, in *applicationpkg.ApplicationPodLogsQuery, opts ...grpc.CallOption) (applicationpkg.ApplicationService_PodLogsClient, error) { return nil, nil } @@ -2175,6 +2183,10 @@ func (c *fakeAppServiceClient) ListResourceLinks(ctx context.Context, in *applic return nil, nil } +func (c *fakeAppServiceClient) GetChangeRevision(ctx context.Context, in *applicationpkg.ChangeRevisionRequest, opts ...grpc.CallOption) (*applicationpkg.ChangeRevisionResponse, error) { + return nil, nil +} + type fakeAcdClient struct{} func (c *fakeAcdClient) ClientOptions() argocdclient.ClientOptions { diff --git a/cmd/event-reporter-server/commands/common.go b/cmd/event-reporter-server/commands/common.go new file mode 100644 index 0000000000000..7ad2c7069df88 --- /dev/null +++ b/cmd/event-reporter-server/commands/common.go @@ -0,0 +1,6 @@ +package commands + +const ( + // cliName is the name of the CLI + cliName = "event-reporter-server" +) diff --git a/cmd/event-reporter-server/commands/event_reporter_server.go b/cmd/event-reporter-server/commands/event_reporter_server.go new file mode 100644 index 0000000000000..c2ce124947eef --- /dev/null +++ b/cmd/event-reporter-server/commands/event_reporter_server.go @@ -0,0 +1,264 @@ +package commands + +import ( + "context" + "fmt" + "math" + "time" + + "github.com/argoproj/argo-cd/v2/pkg/sources_server_client" + + "github.com/argoproj/argo-cd/v2/event_reporter/reporter" + + "github.com/argoproj/argo-cd/v2/event_reporter" + appclient "github.com/argoproj/argo-cd/v2/event_reporter/application" + "github.com/argoproj/argo-cd/v2/pkg/apiclient" + "github.com/argoproj/argo-cd/v2/pkg/codefresh" + + "github.com/argoproj/pkg/stats" + "github.com/redis/go-redis/v9" + log "github.com/sirupsen/logrus" + "github.com/spf13/cobra" + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/tools/clientcmd" + + cmdutil "github.com/argoproj/argo-cd/v2/cmd/util" + "github.com/argoproj/argo-cd/v2/common" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + appclientset "github.com/argoproj/argo-cd/v2/pkg/client/clientset/versioned" + repoapiclient "github.com/argoproj/argo-cd/v2/reposerver/apiclient" + servercache "github.com/argoproj/argo-cd/v2/server/cache" + cacheutil "github.com/argoproj/argo-cd/v2/util/cache" + "github.com/argoproj/argo-cd/v2/util/cli" + "github.com/argoproj/argo-cd/v2/util/env" + "github.com/argoproj/argo-cd/v2/util/errors" + "github.com/argoproj/argo-cd/v2/util/kube" + "github.com/argoproj/argo-cd/v2/util/tls" +) + +const ( + failureRetryCountEnv = "EVENT_REPORTER_K8S_RETRY_COUNT" + failureRetryPeriodMilliSecondsEnv = "EVENT_REPORTE_K8S_RETRY_DURATION_MILLISECONDS" +) + +var ( + failureRetryCount = 0 + failureRetryPeriodMilliSeconds = 100 +) + +func init() { + failureRetryCount = env.ParseNumFromEnv(failureRetryCountEnv, failureRetryCount, 0, 10) + failureRetryPeriodMilliSeconds = env.ParseNumFromEnv(failureRetryPeriodMilliSecondsEnv, failureRetryPeriodMilliSeconds, 0, 1000) +} + +func getApplicationClient(useGrpc bool, address, token string, path string) appclient.ApplicationClient { + if useGrpc { + applicationClientSet, err := apiclient.NewClient(&apiclient.ClientOptions{ + ServerAddr: address, + Insecure: true, + GRPCWeb: true, + PlainText: true, + AuthToken: token, + GRPCWebRootPath: path, + }) + + errors.CheckError(err) + + _, applicationClient, err := applicationClientSet.NewApplicationClient() + + errors.CheckError(err) + + return applicationClient + } + return appclient.NewHttpApplicationClient(token, address, path) +} + +// NewCommand returns a new instance of an event reporter command +func NewCommand() *cobra.Command { + var ( + redisClient *redis.Client + insecure bool + listenHost string + listenPort int + metricsHost string + metricsPort int + glogLevel int + clientConfig clientcmd.ClientConfig + repoServerTimeoutSeconds int + repoServerAddress string + applicationServerAddress string + cacheSrc func() (*servercache.Cache, error) + contentSecurityPolicy string + repoServerPlaintext bool + repoServerStrictTLS bool + applicationNamespaces []string + argocdToken string + codefreshTlsInsecure bool + codefreshTlsCertPath string + codefreshUrl string + codefreshToken string + shardingAlgorithm string + runtimeVersion string + rootpath string + useGrpc bool + + rateLimiterEnabled bool + rateLimiterBucketSize int + rateLimiterDuration time.Duration + rateLimiterLearningMode bool + useSourcesServer bool + sourcesServerBaseURL string + ) + command := &cobra.Command{ + Use: cliName, + Short: "Run the Event Reporter server", + Long: "The Event reporter is a server that listens to Kubernetes events and reports them to the Codefresh server.", + DisableAutoGenTag: true, + Run: func(c *cobra.Command, args []string) { + ctx := c.Context() + + vers := common.GetVersion() + namespace, _, err := clientConfig.Namespace() + errors.CheckError(err) + vers.LogStartupInfo( + "Event Reporter Server", + map[string]any{ + "namespace": namespace, + "port": listenPort, + }, + ) + + cli.SetLogFormat(cmdutil.LogFormat) + cli.SetLogLevel(cmdutil.LogLevel) + cli.SetGLogLevel(glogLevel) + + config, err := clientConfig.ClientConfig() + errors.CheckError(err) + errors.CheckError(v1alpha1.SetK8SConfigDefaults(config)) + + cache, err := cacheSrc() + errors.CheckError(err) + + kubeclientset := kubernetes.NewForConfigOrDie(config) + + appclientsetConfig, err := clientConfig.ClientConfig() + errors.CheckError(err) + errors.CheckError(v1alpha1.SetK8SConfigDefaults(appclientsetConfig)) + config.UserAgent = fmt.Sprintf("argocd-server/%s (%s)", vers.Version, vers.Platform) + + if failureRetryCount > 0 { + appclientsetConfig = kube.AddFailureRetryWrapper(appclientsetConfig, failureRetryCount, failureRetryPeriodMilliSeconds) + } + appClientSet := appclientset.NewForConfigOrDie(appclientsetConfig) + tlsConfig := repoapiclient.TLSConfiguration{ + DisableTLS: repoServerPlaintext, + StrictValidation: repoServerStrictTLS, + } + + // Load CA information to use for validating connections to the + // repository server, if strict TLS validation was requested. + if !repoServerPlaintext && repoServerStrictTLS { + pool, err := tls.LoadX509CertPool( + fmt.Sprintf("%s/server/tls/tls.crt", env.StringFromEnv(common.EnvAppConfigPath, common.DefaultAppConfigPath)), + fmt.Sprintf("%s/server/tls/ca.crt", env.StringFromEnv(common.EnvAppConfigPath, common.DefaultAppConfigPath)), + ) + if err != nil { + log.Fatalf("%v", err) + } + tlsConfig.Certificates = pool + } + + repoclientset := repoapiclient.NewRepoServerClientset(repoServerAddress, repoServerTimeoutSeconds, tlsConfig) + + eventReporterServerOpts := event_reporter.EventReporterServerOpts{ + ListenPort: listenPort, + ListenHost: listenHost, + MetricsPort: metricsPort, + MetricsHost: metricsHost, + Namespace: namespace, + KubeClientset: kubeclientset, + AppClientset: appClientSet, + RepoClientset: repoclientset, + Cache: cache, + RedisClient: redisClient, + ApplicationNamespaces: applicationNamespaces, + ApplicationServiceClient: getApplicationClient(useGrpc, applicationServerAddress, argocdToken, rootpath), + CodefreshConfig: &codefresh.CodefreshConfig{ + BaseURL: codefreshUrl, + AuthToken: codefreshToken, + TlsInsecure: codefreshTlsInsecure, + CaCertPath: codefreshTlsCertPath, + RuntimeVersion: runtimeVersion, + }, + RateLimiterOpts: &reporter.RateLimiterOpts{ + Enabled: rateLimiterEnabled, + Rate: rateLimiterDuration, + Capacity: rateLimiterBucketSize, + LearningMode: rateLimiterLearningMode, + }, + UseSourcesServer: useSourcesServer, + SourcesServerConfig: &sources_server_client.SourcesServerConfig{ + BaseURL: sourcesServerBaseURL, + }, + } + + log.Infof("Starting event reporter server with grpc transport %v", useGrpc) + + stats.RegisterStackDumper() + stats.StartStatsTicker(10 * time.Minute) + stats.RegisterHeapDumper("memprofile") + eventReporterServer := event_reporter.NewEventReporterServer(ctx, eventReporterServerOpts) + eventReporterServer.Init(ctx) + lns, err := eventReporterServer.Listen() + errors.CheckError(err) + for { + var closer func() + ctx, cancel := context.WithCancel(ctx) + eventReporterServer.Run(ctx, lns) + cancel() + if closer != nil { + closer() + } + } + }, + } + + clientConfig = cli.AddKubectlFlagsToCmd(command) + command.Flags().StringVar(&rootpath, "argocd-server-path", env.StringFromEnv("ARGOCD_SERVER_ROOTPATH", ""), "Used if Argo CD is running behind reverse proxy under subpath different from /") + command.Flags().BoolVar(&insecure, "insecure", env.ParseBoolFromEnv("EVENT_REPORTER_INSECURE", false), "Run server without TLS") + command.Flags().StringVar(&cmdutil.LogFormat, "logformat", env.StringFromEnv("EVENT_REPORTER_LOGFORMAT", "text"), "Set the logging format. One of: text|json") + command.Flags().StringVar(&cmdutil.LogLevel, "loglevel", env.StringFromEnv("EVENT_REPORTER_LOG_LEVEL", "info"), "Set the logging level. One of: debug|info|warn|error") + command.Flags().IntVar(&glogLevel, "gloglevel", 0, "Set the glog logging level") + command.Flags().StringVar(&applicationServerAddress, "application-server", env.StringFromEnv("EVENT_REPORTER_APPLICATION_SERVER", common.DefaultApplicationServerAddr), "Application server address") + command.Flags().StringVar(&argocdToken, "argocd-token", env.StringFromEnv("ARGOCD_TOKEN", ""), "ArgoCD server JWT token") + command.Flags().StringVar(&repoServerAddress, "repo-server", env.StringFromEnv("EVENT_REPORTER_REPO_SERVER", common.DefaultRepoServerAddr), "Repo server address") + command.AddCommand(cli.NewVersionCmd(cliName)) + command.Flags().StringVar(&listenHost, "address", env.StringFromEnv("EVENT_REPORTER_LISTEN_ADDRESS", common.DefaultAddressEventReporterServer), "Listen on given address") + command.Flags().IntVar(&listenPort, "port", common.DefaultPortEventReporterServer, "Listen on given port") + command.Flags().StringVar(&metricsHost, env.StringFromEnv("EVENT_REPORTER_METRICS_LISTEN_ADDRESS", "metrics-address"), common.DefaultAddressEventReporterServerMetrics, "Listen for metrics on given address") + command.Flags().IntVar(&metricsPort, "metrics-port", common.DefaultPortEventReporterServerMetrics, "Start metrics on given port") + command.Flags().IntVar(&repoServerTimeoutSeconds, "repo-server-timeout-seconds", env.ParseNumFromEnv("EVENT_REPORTER_REPO_SERVER_TIMEOUT_SECONDS", 60, 0, math.MaxInt64), "Repo server RPC call timeout seconds.") + command.Flags().StringVar(&contentSecurityPolicy, "content-security-policy", env.StringFromEnv("EVENT_REPORTER_CONTENT_SECURITY_POLICY", "frame-ancestors 'self';"), "Set Content-Security-Policy header in HTTP responses to `value`. To disable, set to \"\".") + command.Flags().BoolVar(&repoServerPlaintext, "repo-server-plaintext", env.ParseBoolFromEnv("EVENT_REPORTER_REPO_SERVER_PLAINTEXT", false), "Use a plaintext client (non-TLS) to connect to repository server") + command.Flags().BoolVar(&repoServerStrictTLS, "repo-server-strict-tls", env.ParseBoolFromEnv("EVENT_REPORTER_REPO_SERVER_STRICT_TLS", false), "Perform strict validation of TLS certificates when connecting to repo server") + command.Flags().StringVar(&codefreshTlsCertPath, "codefresh-tls-cert-path", env.StringFromEnv("CODEFRESH_SSL_CERT_PATH", ""), "Codefresh TLS CA cert file path") + command.Flags().BoolVar(&codefreshTlsInsecure, "codefresh-tls-insecure", env.ParseBoolFromEnv("CODEFRESH_TLS_INSECURE", false), "Codefresh TLS insecure") + command.Flags().StringVar(&codefreshUrl, "codefresh-url", env.StringFromEnv("CODEFRESH_URL", "https://g.codefresh.io"), "Codefresh API url") + command.Flags().StringVar(&codefreshToken, "codefresh-token", env.StringFromEnv("CODEFRESH_TOKEN", ""), "Codefresh token") + command.Flags().StringVar(&shardingAlgorithm, "sharding-method", env.StringFromEnv(common.EnvEventReporterShardingAlgorithm, common.DefaultEventReporterShardingAlgorithm), "Enables choice of sharding method. Supported sharding methods are : [legacy] ") + command.Flags().StringVar(&runtimeVersion, "codefresh-runtime-version", env.StringFromEnv("CODEFRESH_RUNTIME_VERSION", ""), "Codefresh runtime version to be reported with each event to platform") + command.Flags().StringSliceVar(&applicationNamespaces, "application-namespaces", env.StringsFromEnv("ARGOCD_APPLICATION_NAMESPACES", []string{}, ","), "List of additional namespaces where application resources can be managed in") + command.Flags().BoolVar(&useGrpc, "grpc", env.ParseBoolFromEnv("USE_GRPC", false), "Use grpc for interact with argocd server") + command.Flags().BoolVar(&rateLimiterEnabled, "rate-limiter-enabled", env.ParseBoolFromEnv("RATE_LIMITER_ENABLED", false), "Use rate limiter for prevent queue to be overflowed") + command.Flags().IntVar(&rateLimiterBucketSize, "rate-limiter-bucket-size", env.ParseNumFromEnv("RATE_LIMITER_BUCKET_SIZE", math.MaxInt, 0, math.MaxInt), "The maximum amount of requests allowed per window.") + command.Flags().DurationVar(&rateLimiterDuration, "rate-limiter-period", env.ParseDurationFromEnv("RATE_LIMITER_DURATION", 24*time.Hour, 0, math.MaxInt64), "The rate limit window size.") + command.Flags().BoolVar(&rateLimiterLearningMode, "rate-limiter-learning-mode", env.ParseBoolFromEnv("RATE_LIMITER_LEARNING_MODE_ENABLED", false), "The rate limit enabled in learning mode ( not blocking sending to queue but logging it )") + command.Flags().BoolVar(&useSourcesServer, "use-sources-server", env.ParseBoolFromEnv("SOURCES_SERVER_ENABLED", false), "Use sources-server instead of repo-server fork") + command.Flags().StringVar(&sourcesServerBaseURL, "sources-server-base-url", env.StringFromEnv("SOURCES_SERVER_BASE_URL", common.DefaultSourcesServerAddr), "Sources-server base URL") + cacheSrc = servercache.AddCacheFlagsToCmd(command, cacheutil.Options{ + OnClientCreated: func(client *redis.Client) { + redisClient = client + }, + }) + return command +} diff --git a/cmd/main.go b/cmd/main.go index 92eb27049c9fc..02ff304b47132 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -8,6 +8,7 @@ import ( "github.com/spf13/cobra" + changerevisioncontroller "github.com/argoproj/argo-cd/v2/cmd/application-change-revision-controller/commands" appcontroller "github.com/argoproj/argo-cd/v2/cmd/argocd-application-controller/commands" applicationset "github.com/argoproj/argo-cd/v2/cmd/argocd-applicationset-controller/commands" cmpserver "github.com/argoproj/argo-cd/v2/cmd/argocd-cmp-server/commands" @@ -19,6 +20,7 @@ import ( reposerver "github.com/argoproj/argo-cd/v2/cmd/argocd-repo-server/commands" apiserver "github.com/argoproj/argo-cd/v2/cmd/argocd-server/commands" cli "github.com/argoproj/argo-cd/v2/cmd/argocd/commands" + eventreporterserver "github.com/argoproj/argo-cd/v2/cmd/event-reporter-server/commands" ) const ( @@ -40,6 +42,10 @@ func main() { isCLI = true case "argocd-server": command = apiserver.NewCommand() + case "event-reporter-server": + command = eventreporterserver.NewCommand() + case "argocd-application-change-revision-controller": + command = changerevisioncontroller.NewCommand() case "argocd-application-controller": command = appcontroller.NewCommand() case "argocd-repo-server": diff --git a/common/cf_common.go b/common/cf_common.go new file mode 100644 index 0000000000000..2a5a6c260bd2f --- /dev/null +++ b/common/cf_common.go @@ -0,0 +1,44 @@ +package common + +// Default service addresses and URLS of Argo CD internal services +const ( + // DefaultApplicationServerAddr is the HTTP address of the Argo CD server + DefaultApplicationServerAddr = "argo-cd-server:80" + // DefaultRedisHaProxyAddr is the default HTTP address of the sources server + DefaultSourcesServerAddr = "sources-server:8090" +) + +// Default listener ports for ArgoCD components +const ( + DefaultPortEventReporterServerMetrics = 8087 + DefaultPortEventReporterServer = 8088 + + DefaultPortACRServer = 8090 +) + +// DefaultAddressAPIServer for ArgoCD components +const ( + DefaultAddressEventReporterServer = "0.0.0.0" + DefaultAddressACRController = "0.0.0.0" + DefaultAddressEventReporterServerMetrics = "0.0.0.0" +) + +// Environment variables for tuning and debugging Argo CD +const ( + // EnvApplicationEventCacheDuration controls the expiration of application events cache + EnvApplicationEventCacheDuration = "ARGOCD_APP_EVENTS_CACHE_DURATION" + // EnvResourceEventCacheDuration controls the expiration of resource events cache + EnvResourceEventCacheDuration = "ARGOCD_RESOURCE_EVENTS_CACHE_DURATION" + // EnvEventReporterShardingAlgorithm is the distribution sharding algorithm to be used: legacy + EnvEventReporterShardingAlgorithm = "EVENT_REPORTER_SHARDING_ALGORITHM" + // EnvEventReporterReplicas is the number of EventReporter replicas + EnvEventReporterReplicas = "EVENT_REPORTER_REPLICAS" + // EnvEventReporterShard is the shard number that should be handled by reporter + EnvEventReporterShard = "EVENT_REPORTER_SHARD" +) + +// CF Event reporter constants +const ( + EventReporterLegacyShardingAlgorithm = "legacy" + DefaultEventReporterShardingAlgorithm = EventReporterLegacyShardingAlgorithm +) diff --git a/controller/appcontroller.go b/controller/appcontroller.go index 4787457fbf821..18890ea8e07e6 100644 --- a/controller/appcontroller.go +++ b/controller/appcontroller.go @@ -576,7 +576,7 @@ func (ctrl *ApplicationController) getResourceTree(a *appv1.Application, managed if err != nil { return nil, fmt.Errorf("failed to unmarshal target state of managed resources: %w", err) } - nodes = append(nodes, appv1.ResourceNode{ + newNode := appv1.ResourceNode{ ResourceRef: appv1.ResourceRef{ Version: target.GroupVersionKind().Version, Name: managedResource.Name, @@ -584,7 +584,16 @@ func (ctrl *ApplicationController) getResourceTree(a *appv1.Application, managed Group: managedResource.Group, Namespace: managedResource.Namespace, }, - }) + } + + if targetLabels := target.GetLabels(); targetLabels != nil { + newNode.Labels = targetLabels + } + if targetAnnotations := target.GetAnnotations(); targetAnnotations != nil { + newNode.Annotations = targetAnnotations + } + + nodes = append(nodes, newNode) } else { managedResourcesKeys = append(managedResourcesKeys, kube.GetResourceKey(live)) } @@ -1624,6 +1633,7 @@ func (ctrl *ApplicationController) processAppRefreshQueueItem() (processNext boo return } origApp = origApp.DeepCopy() + needRefresh, refreshType, comparisonLevel := ctrl.needRefreshAppStatus(origApp, ctrl.statusRefreshTimeout, ctrl.statusHardRefreshTimeout) if !needRefresh { diff --git a/controller/appcontroller_test.go b/controller/appcontroller_test.go index cd3f84559984e..482852306c5d3 100644 --- a/controller/appcontroller_test.go +++ b/controller/appcontroller_test.go @@ -1020,7 +1020,11 @@ func TestFinalizeAppDeletion(t *testing.T) { app.Spec.Destination.Namespace = test.FakeArgoCDNamespace ctrl := newFakeController(&fakeData{ manifestResponses: []*apiclient.ManifestResponse{{ - Manifests: []string{fakePostDeleteHook}, + Manifests: []*apiclient.Manifest{ + { + CompiledManifest: fakePostDeleteHook, + }, + }, }}, apps: []runtime.Object{app, &defaultProj}, managedLiveObjs: map[kube.ResourceKey]*unstructured.Unstructured{}, @@ -1062,7 +1066,11 @@ func TestFinalizeAppDeletion(t *testing.T) { require.NoError(t, unstructured.SetNestedField(liveHook.Object, conditions, "status", "conditions")) ctrl := newFakeController(&fakeData{ manifestResponses: []*apiclient.ManifestResponse{{ - Manifests: []string{fakePostDeleteHook}, + Manifests: []*apiclient.Manifest{ + { + CompiledManifest: fakePostDeleteHook, + }, + }, }}, apps: []runtime.Object{app, &defaultProj}, managedLiveObjs: map[kube.ResourceKey]*unstructured.Unstructured{ @@ -1106,7 +1114,20 @@ func TestFinalizeAppDeletion(t *testing.T) { require.NoError(t, unstructured.SetNestedField(liveHook.Object, conditions, "status", "conditions")) ctrl := newFakeController(&fakeData{ manifestResponses: []*apiclient.ManifestResponse{{ - Manifests: []string{fakeRoleBinding, fakeRole, fakeServiceAccount, fakePostDeleteHook}, + Manifests: []*apiclient.Manifest{ + { + CompiledManifest: fakeRoleBinding, + }, + { + CompiledManifest: fakeRole, + }, + { + CompiledManifest: fakeServiceAccount, + }, + { + CompiledManifest: fakePostDeleteHook, + }, + }, }}, apps: []runtime.Object{app, &defaultProj}, managedLiveObjs: map[kube.ResourceKey]*unstructured.Unstructured{ @@ -1168,7 +1189,7 @@ func TestNormalizeApplication(t *testing.T) { data := fakeData{ apps: []runtime.Object{app, &defaultProj}, manifestResponse: &apiclient.ManifestResponse{ - Manifests: []string{}, + Manifests: []*apiclient.Manifest{}, Namespace: test.FakeDestNamespace, Server: test.FakeClusterURL, Revision: "abc123", @@ -1272,6 +1293,9 @@ func TestGetResourceTree_HasOrphanedResources(t *testing.T) { managedDeploy := v1alpha1.ResourceNode{ ResourceRef: v1alpha1.ResourceRef{Group: "apps", Kind: "Deployment", Namespace: "default", Name: "nginx-deployment", Version: "v1"}, + Labels: map[string]string{ + "app": "nginx", + }, } orphanedDeploy1 := v1alpha1.ResourceNode{ ResourceRef: v1alpha1.ResourceRef{Group: "apps", Kind: "Deployment", Namespace: "default", Name: "deploy1"}, @@ -1663,7 +1687,7 @@ func TestUpdateReconciledAt(t *testing.T) { ctrl := newFakeController(&fakeData{ apps: []runtime.Object{app, &defaultProj}, manifestResponse: &apiclient.ManifestResponse{ - Manifests: []string{}, + Manifests: []*apiclient.Manifest{}, Namespace: test.FakeDestNamespace, Server: test.FakeClusterURL, Revision: "abc123", @@ -1794,7 +1818,7 @@ apps/Deployment: ctrl := newFakeController(&fakeData{ apps: []runtime.Object{tc.app, &defaultProj}, manifestResponse: &apiclient.ManifestResponse{ - Manifests: []string{}, + Manifests: []*apiclient.Manifest{}, Namespace: test.FakeDestNamespace, Server: test.FakeClusterURL, Revision: "abc123", @@ -1858,7 +1882,7 @@ apps/Deployment: ctrl := newFakeControllerWithResync(&fakeData{ apps: []runtime.Object{app, &defaultProj}, manifestResponse: &apiclient.ManifestResponse{ - Manifests: []string{}, + Manifests: []*apiclient.Manifest{}, Namespace: test.FakeDestNamespace, Server: test.FakeClusterURL, Revision: "abc123", @@ -1925,7 +1949,7 @@ func TestProjectErrorToCondition(t *testing.T) { ctrl := newFakeController(&fakeData{ apps: []runtime.Object{app, &defaultProj}, manifestResponse: &apiclient.ManifestResponse{ - Manifests: []string{}, + Manifests: []*apiclient.Manifest{}, Namespace: test.FakeDestNamespace, Server: test.FakeClusterURL, Revision: "abc123", @@ -2083,7 +2107,7 @@ func TestProcessRequestedAppOperation_RunningPreviouslyFailed(t *testing.T) { data := &fakeData{ apps: []runtime.Object{app, &defaultProj}, manifestResponse: &apiclient.ManifestResponse{ - Manifests: []string{}, + Manifests: []*apiclient.Manifest{}, Namespace: test.FakeDestNamespace, Server: test.FakeClusterURL, Revision: "abc123", @@ -2116,7 +2140,7 @@ func TestProcessRequestedAppOperation_HasRetriesTerminated(t *testing.T) { data := &fakeData{ apps: []runtime.Object{app, &defaultProj}, manifestResponse: &apiclient.ManifestResponse{ - Manifests: []string{}, + Manifests: []*apiclient.Manifest{}, Namespace: test.FakeDestNamespace, Server: test.FakeClusterURL, Revision: "abc123", @@ -2147,7 +2171,7 @@ func TestProcessRequestedAppOperation_Successful(t *testing.T) { ctrl := newFakeController(&fakeData{ apps: []runtime.Object{app, &defaultProj}, manifestResponses: []*apiclient.ManifestResponse{{ - Manifests: []string{}, + Manifests: []*apiclient.Manifest{}, }}, }, nil) fakeAppCs := ctrl.applicationClientset.(*appclientset.Clientset) @@ -2173,7 +2197,7 @@ func TestGetAppHosts(t *testing.T) { data := &fakeData{ apps: []runtime.Object{app, &defaultProj}, manifestResponse: &apiclient.ManifestResponse{ - Manifests: []string{}, + Manifests: []*apiclient.Manifest{}, Namespace: test.FakeDestNamespace, Server: test.FakeClusterURL, Revision: "abc123", @@ -2669,7 +2693,7 @@ func TestSyncTimeout(t *testing.T) { ctrl := newFakeController(&fakeData{ apps: []runtime.Object{app, &defaultProj}, manifestResponses: []*apiclient.ManifestResponse{{ - Manifests: []string{}, + Manifests: []*apiclient.Manifest{}, }}, }, nil) diff --git a/controller/cache/cache.go b/controller/cache/cache.go index 73a8d0bc60452..9899c1ac8628d 100644 --- a/controller/cache/cache.go +++ b/controller/cache/cache.go @@ -284,7 +284,7 @@ func asResourceNode(r *clustercache.Resource) appv1.ResourceNode { if resourceInfo.Health != nil { resHealth = &appv1.HealthStatus{Status: resourceInfo.Health.Status, Message: resourceInfo.Health.Message} } - return appv1.ResourceNode{ + result := appv1.ResourceNode{ ResourceRef: appv1.ResourceRef{ UID: string(r.Ref.UID), Name: r.Ref.Name, @@ -301,6 +301,18 @@ func asResourceNode(r *clustercache.Resource) appv1.ResourceNode { Health: resHealth, CreatedAt: r.CreationTimestamp, } + + if r.Resource != nil { + if labels := r.Resource.GetLabels(); labels != nil { + result.Labels = labels + } + if annotations := r.Resource.GetAnnotations(); annotations != nil { + delete(annotations, "kubectl.kubernetes.io/last-applied-configuration") + result.Annotations = annotations + } + } + + return result } func resInfo(r *clustercache.Resource) *ResourceInfo { diff --git a/controller/state.go b/controller/state.go index 785aba9129213..a5bd86d878572 100644 --- a/controller/state.go +++ b/controller/state.go @@ -208,7 +208,7 @@ func (m *appStateManager) GetRepoObjs(app *v1alpha1.Application, sources []v1alp if err != nil { return nil, nil, false, fmt.Errorf("failed to get repo %q: %w", source.RepoURL, err) } - kustomizeOptions, err := kustomizeSettings.GetOptions(source) + kustomizeOptions, err := kustomizeSettings.GetOptions(source, m.settingsMgr.GetKustomizeSetNamespaceEnabled()) if err != nil { return nil, nil, false, fmt.Errorf("failed to get Kustomize options for source %d of %d: %w", i+1, len(sources), err) } @@ -290,12 +290,13 @@ func (m *appStateManager) GetRepoObjs(app *v1alpha1.Application, sources []v1alp ProjectSourceRepos: proj.Spec.SourceRepos, AnnotationManifestGeneratePaths: app.GetAnnotation(v1alpha1.AnnotationKeyManifestGeneratePaths), InstallationID: installationID, + ApplicationMetadata: &app.ObjectMeta, }) if err != nil { return nil, nil, false, fmt.Errorf("failed to generate manifest for source %d of %d: %w", i+1, len(sources), err) } - targetObj, err := unmarshalManifests(manifestInfo.Manifests) + targetObj, err := unmarshalManifests(manifestInfo.GetCompiledManifests()) if err != nil { return nil, nil, false, fmt.Errorf("failed to unmarshal manifests for source %d of %d: %w", i+1, len(sources), err) } @@ -611,13 +612,14 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *v1 liveObjByKey, err := m.liveStateCache.GetManagedLiveObjs(app, targetObjs) if err != nil { + logCtx.Errorf("Failed to load live state: %v", err) liveObjByKey = make(map[kubeutil.ResourceKey]*unstructured.Unstructured) msg := fmt.Sprintf("Failed to load live state: %s", err.Error()) conditions = append(conditions, v1alpha1.ApplicationCondition{Type: v1alpha1.ApplicationConditionComparisonError, Message: msg, LastTransitionTime: &now}) failedToLoadObjs = true } - logCtx.Debugf("Retrieved live manifests") + logCtx.Debugf("Retrieved live manifests, amount of live objects: %d", len(liveObjByKey)) // filter out all resources which are not permitted in the application project for k, v := range liveObjByKey { @@ -629,6 +631,7 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *v1 return clusters, nil }) if err != nil { + logCtx.Infof("Failed to check if live resource %q is permitted in project %q: %v", k.String(), app.Spec.Project, err) msg := fmt.Sprintf("Failed to check if live resource %q is permitted in project %q: %s", k.String(), app.Spec.Project, err.Error()) conditions = append(conditions, v1alpha1.ApplicationCondition{Type: v1alpha1.ApplicationConditionComparisonError, Message: msg, LastTransitionTime: &now}) failedToLoadObjs = true @@ -693,6 +696,8 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *v1 } } + logCtx.Debugf("Resources before reconciliation: target %d, live %d", len(targetObjs), len(liveObjByKey)) + reconciliation := sync.Reconcile(targetObjs, liveObjByKey, app.Spec.Destination.Namespace, infoProvider) ts.AddCheckpoint("live_ms") @@ -704,6 +709,7 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *v1 manifestRevisions := make([]string, 0) for _, manifestInfo := range manifestInfos { + logCtx.Infof("Manifest for revision %s has been generated", manifestInfo.Revision) manifestRevisions = append(manifestRevisions, manifestInfo.Revision) } @@ -772,6 +778,9 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *v1 syncCode := v1alpha1.SyncStatusCodeSynced managedResources := make([]managedResource, len(reconciliation.Target)) resourceSummaries := make([]v1alpha1.ResourceStatus, len(reconciliation.Target)) + + logCtx.Debugf("Resources after reconciliation: target %d, live %d", len(reconciliation.Target), len(reconciliation.Live)) + for i, targetObj := range reconciliation.Target { liveObj := reconciliation.Live[i] obj := liveObj @@ -822,6 +831,17 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *v1 // the source object, don't store sync status, and do not affect // overall sync status } else if !isManagedNs && (diffResult.Modified || targetObj == nil || liveObj == nil) { + // logging for precisely, can be removed in future + if diffResult.Modified { + logCtx.Debugf("Resource %s is out of sync, because diff between live and desired state", resState.Name) + logCtx.Debugf("Live state: %s", string(diffResult.NormalizedLive)) + logCtx.Debugf("Desired state: %s", string(diffResult.PredictedLive)) + } else if targetObj == nil { + logCtx.Debugf("Resource %s is out of sync, because target object is nil", resState.Name) + } else if liveObj == nil { + logCtx.Debugf("Resource %s is out of sync, because live object is nil", resState.Name) + } + // Set resource state to OutOfSync since one of the following is true: // * target and live resource are different // * target resource not defined and live resource is extra @@ -872,6 +892,7 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *v1 if failedToLoadObjs { syncCode = v1alpha1.SyncStatusCodeUnknown } else if app.HasChangedManagedNamespaceMetadata() { + logCtx.Infof("Application has changed managedNamespaceMetadata, marking application as out of sync") syncCode = v1alpha1.SyncStatusCodeOutOfSync } var revision string diff --git a/controller/state_test.go b/controller/state_test.go index 2efc51718f9ef..291680fd6c94d 100644 --- a/controller/state_test.go +++ b/controller/state_test.go @@ -37,7 +37,7 @@ func TestCompareAppStateEmpty(t *testing.T) { app := newFakeApp() data := fakeData{ manifestResponse: &apiclient.ManifestResponse{ - Manifests: []string{}, + Manifests: []*apiclient.Manifest{}, Namespace: test.FakeDestNamespace, Server: test.FakeClusterURL, Revision: "abc123", @@ -101,7 +101,7 @@ func TestCompareAppStateNamespaceMetadataDiffers(t *testing.T) { data := fakeData{ manifestResponse: &apiclient.ManifestResponse{ - Manifests: []string{}, + Manifests: []*apiclient.Manifest{}, Namespace: test.FakeDestNamespace, Server: test.FakeClusterURL, Revision: "abc123", @@ -148,7 +148,9 @@ func TestCompareAppStateNamespaceMetadataDiffersToManifest(t *testing.T) { data := fakeData{ manifestResponse: &apiclient.ManifestResponse{ - Manifests: []string{toJSON(t, liveNs)}, + Manifests: []*apiclient.Manifest{ + {CompiledManifest: toJSON(t, liveNs)}, + }, Namespace: test.FakeDestNamespace, Server: test.FakeClusterURL, Revision: "abc123", @@ -206,7 +208,7 @@ func TestCompareAppStateNamespaceMetadata(t *testing.T) { data := fakeData{ manifestResponse: &apiclient.ManifestResponse{ - Manifests: []string{}, + Manifests: []*apiclient.Manifest{}, Namespace: test.FakeDestNamespace, Server: test.FakeClusterURL, Revision: "abc123", @@ -267,7 +269,7 @@ func TestCompareAppStateNamespaceMetadataIsTheSame(t *testing.T) { data := fakeData{ manifestResponse: &apiclient.ManifestResponse{ - Manifests: []string{}, + Manifests: []*apiclient.Manifest{}, Namespace: test.FakeDestNamespace, Server: test.FakeClusterURL, Revision: "abc123", @@ -295,7 +297,11 @@ func TestCompareAppStateMissing(t *testing.T) { data := fakeData{ apps: []runtime.Object{app}, manifestResponse: &apiclient.ManifestResponse{ - Manifests: []string{PodManifest}, + Manifests: []*apiclient.Manifest{ + { + CompiledManifest: PodManifest, + }, + }, Namespace: test.FakeDestNamespace, Server: test.FakeClusterURL, Revision: "abc123", @@ -325,7 +331,7 @@ func TestCompareAppStateExtra(t *testing.T) { key := kube.ResourceKey{Group: "", Kind: "Pod", Namespace: test.FakeDestNamespace, Name: app.Name} data := fakeData{ manifestResponse: &apiclient.ManifestResponse{ - Manifests: []string{}, + Manifests: []*apiclient.Manifest{}, Namespace: test.FakeDestNamespace, Server: test.FakeClusterURL, Revision: "abc123", @@ -358,7 +364,11 @@ func TestCompareAppStateHook(t *testing.T) { data := fakeData{ apps: []runtime.Object{app}, manifestResponse: &apiclient.ManifestResponse{ - Manifests: []string{string(podBytes)}, + Manifests: []*apiclient.Manifest{ + { + CompiledManifest: string(podBytes), + }, + }, Namespace: test.FakeDestNamespace, Server: test.FakeClusterURL, Revision: "abc123", @@ -390,7 +400,11 @@ func TestCompareAppStateSkipHook(t *testing.T) { data := fakeData{ apps: []runtime.Object{app}, manifestResponse: &apiclient.ManifestResponse{ - Manifests: []string{string(podBytes)}, + Manifests: []*apiclient.Manifest{ + { + CompiledManifest: string(podBytes), + }, + }, Namespace: test.FakeDestNamespace, Server: test.FakeClusterURL, Revision: "abc123", @@ -420,7 +434,7 @@ func TestCompareAppStateCompareOptionIgnoreExtraneous(t *testing.T) { data := fakeData{ apps: []runtime.Object{app}, manifestResponse: &apiclient.ManifestResponse{ - Manifests: []string{}, + Manifests: []*apiclient.Manifest{}, Namespace: test.FakeDestNamespace, Server: test.FakeClusterURL, Revision: "abc123", @@ -452,7 +466,7 @@ func TestCompareAppStateExtraHook(t *testing.T) { key := kube.ResourceKey{Group: "", Kind: "Pod", Namespace: test.FakeDestNamespace, Name: app.Name} data := fakeData{ manifestResponse: &apiclient.ManifestResponse{ - Manifests: []string{}, + Manifests: []*apiclient.Manifest{}, Namespace: test.FakeDestNamespace, Server: test.FakeClusterURL, Revision: "abc123", @@ -483,7 +497,9 @@ func TestAppRevisionsSingleSource(t *testing.T) { obj1.SetNamespace(test.FakeDestNamespace) data := fakeData{ manifestResponse: &apiclient.ManifestResponse{ - Manifests: []string{toJSON(t, obj1)}, + Manifests: []*apiclient.Manifest{ + {CompiledManifest: toJSON(t, obj1)}, + }, Namespace: test.FakeDestNamespace, Server: test.FakeClusterURL, Revision: "abc123", @@ -510,19 +526,23 @@ func TestAppRevisionsMultiSource(t *testing.T) { data := fakeData{ manifestResponses: []*apiclient.ManifestResponse{ { - Manifests: []string{toJSON(t, obj1)}, + Manifests: []*apiclient.Manifest{ + {CompiledManifest: toJSON(t, obj1)}, + }, Namespace: test.FakeDestNamespace, Server: test.FakeClusterURL, Revision: "abc123", }, { - Manifests: []string{toJSON(t, obj1)}, + Manifests: []*apiclient.Manifest{ + {CompiledManifest: toJSON(t, obj1)}, + }, Namespace: test.FakeDestNamespace, Server: test.FakeClusterURL, Revision: "def456", }, { - Manifests: []string{}, + Manifests: []*apiclient.Manifest{}, Namespace: test.FakeDestNamespace, Server: test.FakeClusterURL, Revision: "ghi789", @@ -569,7 +589,13 @@ func TestCompareAppStateDuplicatedNamespacedResources(t *testing.T) { app := newFakeApp() data := fakeData{ manifestResponse: &apiclient.ManifestResponse{ - Manifests: []string{toJSON(t, obj1), toJSON(t, obj2), toJSON(t, obj3), toJSON(t, obj4), toJSON(t, obj5)}, + Manifests: []*apiclient.Manifest{ + {CompiledManifest: toJSON(t, obj1)}, + {CompiledManifest: toJSON(t, obj2)}, + {CompiledManifest: toJSON(t, obj3)}, + {CompiledManifest: toJSON(t, obj4)}, + {CompiledManifest: toJSON(t, obj5)}, + }, Namespace: test.FakeDestNamespace, Server: test.FakeClusterURL, Revision: "abc123", @@ -611,7 +637,7 @@ func TestCompareAppStateManagedNamespaceMetadataWithLiveNsDoesNotGetPruned(t *te data := fakeData{ manifestResponse: &apiclient.ManifestResponse{ - Manifests: []string{}, + Manifests: []*apiclient.Manifest{}, Namespace: test.FakeDestNamespace, Server: test.FakeClusterURL, Revision: "abc123", @@ -664,7 +690,7 @@ func TestCompareAppStateWithManifestGeneratePath(t *testing.T) { data := fakeData{ manifestResponse: &apiclient.ManifestResponse{ - Manifests: []string{}, + Manifests: []*apiclient.Manifest{}, Namespace: test.FakeDestNamespace, Server: test.FakeClusterURL, Revision: "abc123", @@ -697,7 +723,7 @@ func TestSetHealth(t *testing.T) { ctrl := newFakeController(&fakeData{ apps: []runtime.Object{app, &defaultProj}, manifestResponse: &apiclient.ManifestResponse{ - Manifests: []string{}, + Manifests: []*apiclient.Manifest{}, Namespace: test.FakeDestNamespace, Server: test.FakeClusterURL, Revision: "abc123", @@ -734,7 +760,7 @@ func TestPreserveStatusTimestamp(t *testing.T) { ctrl := newFakeController(&fakeData{ apps: []runtime.Object{app, &defaultProj}, manifestResponse: &apiclient.ManifestResponse{ - Manifests: []string{}, + Manifests: []*apiclient.Manifest{}, Namespace: test.FakeDestNamespace, Server: test.FakeClusterURL, Revision: "abc123", @@ -771,7 +797,7 @@ func TestSetHealthSelfReferencedApp(t *testing.T) { ctrl := newFakeController(&fakeData{ apps: []runtime.Object{app, &defaultProj}, manifestResponse: &apiclient.ManifestResponse{ - Manifests: []string{}, + Manifests: []*apiclient.Manifest{}, Namespace: test.FakeDestNamespace, Server: test.FakeClusterURL, Revision: "abc123", @@ -991,7 +1017,7 @@ func TestSignedResponseNoSignatureRequired(t *testing.T) { app := newFakeApp() data := fakeData{ manifestResponse: &apiclient.ManifestResponse{ - Manifests: []string{}, + Manifests: []*apiclient.Manifest{}, Namespace: test.FakeDestNamespace, Server: test.FakeClusterURL, Revision: "abc123", @@ -1018,7 +1044,7 @@ func TestSignedResponseNoSignatureRequired(t *testing.T) { app := newFakeApp() data := fakeData{ manifestResponse: &apiclient.ManifestResponse{ - Manifests: []string{}, + Manifests: []*apiclient.Manifest{}, Namespace: test.FakeDestNamespace, Server: test.FakeClusterURL, Revision: "abc123", @@ -1050,7 +1076,7 @@ func TestSignedResponseSignatureRequired(t *testing.T) { app := newFakeApp() data := fakeData{ manifestResponse: &apiclient.ManifestResponse{ - Manifests: []string{}, + Manifests: []*apiclient.Manifest{}, Namespace: test.FakeDestNamespace, Server: test.FakeClusterURL, Revision: "abc123", @@ -1077,7 +1103,7 @@ func TestSignedResponseSignatureRequired(t *testing.T) { app := newFakeApp() data := fakeData{ manifestResponse: &apiclient.ManifestResponse{ - Manifests: []string{}, + Manifests: []*apiclient.Manifest{}, Namespace: test.FakeDestNamespace, Server: test.FakeClusterURL, Revision: "abc123", @@ -1104,7 +1130,7 @@ func TestSignedResponseSignatureRequired(t *testing.T) { app := newFakeApp() data := fakeData{ manifestResponse: &apiclient.ManifestResponse{ - Manifests: []string{}, + Manifests: []*apiclient.Manifest{}, Namespace: test.FakeDestNamespace, Server: test.FakeClusterURL, Revision: "abc123", @@ -1131,7 +1157,7 @@ func TestSignedResponseSignatureRequired(t *testing.T) { app := newFakeApp() data := fakeData{ manifestResponse: &apiclient.ManifestResponse{ - Manifests: []string{}, + Manifests: []*apiclient.Manifest{}, Namespace: test.FakeDestNamespace, Server: test.FakeClusterURL, Revision: "abc123", @@ -1159,7 +1185,7 @@ func TestSignedResponseSignatureRequired(t *testing.T) { app := newFakeApp() data := fakeData{ manifestResponse: &apiclient.ManifestResponse{ - Manifests: []string{}, + Manifests: []*apiclient.Manifest{}, Namespace: test.FakeDestNamespace, Server: test.FakeClusterURL, Revision: "abc123", @@ -1189,7 +1215,7 @@ func TestSignedResponseSignatureRequired(t *testing.T) { app := newFakeApp() data := fakeData{ manifestResponse: &apiclient.ManifestResponse{ - Manifests: []string{}, + Manifests: []*apiclient.Manifest{}, Namespace: test.FakeDestNamespace, Server: test.FakeClusterURL, Revision: "abc123", @@ -1221,7 +1247,7 @@ func TestSignedResponseSignatureRequired(t *testing.T) { app := newFakeApp() data := fakeData{ manifestResponse: &apiclient.ManifestResponse{ - Manifests: []string{}, + Manifests: []*apiclient.Manifest{}, Namespace: test.FakeDestNamespace, Server: test.FakeClusterURL, Revision: "abc123", @@ -1249,7 +1275,7 @@ func TestSignedResponseSignatureRequired(t *testing.T) { app := newFakeApp() data := fakeData{ manifestResponse: &apiclient.ManifestResponse{ - Manifests: []string{}, + Manifests: []*apiclient.Manifest{}, Namespace: test.FakeDestNamespace, Server: test.FakeClusterURL, Revision: "abc123", @@ -1388,7 +1414,7 @@ func TestIsLiveResourceManaged(t *testing.T) { ctrl := newFakeController(&fakeData{ apps: []runtime.Object{app, &defaultProj}, manifestResponse: &apiclient.ManifestResponse{ - Manifests: []string{}, + Manifests: []*apiclient.Manifest{}, Namespace: test.FakeDestNamespace, Server: test.FakeClusterURL, Revision: "abc123", @@ -1488,9 +1514,9 @@ func TestUseDiffCache(t *testing.T) { manifestInfos := func(revision string) []*apiclient.ManifestResponse { return []*apiclient.ManifestResponse{ { - Manifests: []string{ - "{\"apiVersion\":\"v1\",\"kind\":\"Service\",\"metadata\":{\"labels\":{\"app.kubernetes.io/instance\":\"httpbin\"},\"name\":\"httpbin-svc\",\"namespace\":\"httpbin\"},\"spec\":{\"ports\":[{\"name\":\"http-port\",\"port\":7777,\"targetPort\":80},{\"name\":\"test\",\"port\":333}],\"selector\":{\"app\":\"httpbin\"}}}", - "{\"apiVersion\":\"apps/v1\",\"kind\":\"Deployment\",\"metadata\":{\"labels\":{\"app.kubernetes.io/instance\":\"httpbin\"},\"name\":\"httpbin-deployment\",\"namespace\":\"httpbin\"},\"spec\":{\"replicas\":2,\"selector\":{\"matchLabels\":{\"app\":\"httpbin\"}},\"template\":{\"metadata\":{\"labels\":{\"app\":\"httpbin\"}},\"spec\":{\"containers\":[{\"image\":\"kennethreitz/httpbin\",\"imagePullPolicy\":\"Always\",\"name\":\"httpbin\",\"ports\":[{\"containerPort\":80}]}]}}}}", + Manifests: []*apiclient.Manifest{ + {CompiledManifest: "{\"apiVersion\":\"v1\",\"kind\":\"Service\",\"metadata\":{\"labels\":{\"app.kubernetes.io/instance\":\"httpbin\"},\"name\":\"httpbin-svc\",\"namespace\":\"httpbin\"},\"spec\":{\"ports\":[{\"name\":\"http-port\",\"port\":7777,\"targetPort\":80},{\"name\":\"test\",\"port\":333}],\"selector\":{\"app\":\"httpbin\"}}}"}, + {CompiledManifest: "{\"apiVersion\":\"apps/v1\",\"kind\":\"Deployment\",\"metadata\":{\"labels\":{\"app.kubernetes.io/instance\":\"httpbin\"},\"name\":\"httpbin-deployment\",\"namespace\":\"httpbin\"},\"spec\":{\"replicas\":2,\"selector\":{\"matchLabels\":{\"app\":\"httpbin\"}},\"template\":{\"metadata\":{\"labels\":{\"app\":\"httpbin\"}},\"spec\":{\"containers\":[{\"image\":\"kennethreitz/httpbin\",\"imagePullPolicy\":\"Always\",\"name\":\"httpbin\",\"ports\":[{\"containerPort\":80}]}]}}}}"}, }, Namespace: "", Server: "", @@ -1798,7 +1824,7 @@ func TestCompareAppStateDefaultRevisionUpdated(t *testing.T) { app := newFakeApp() data := fakeData{ manifestResponse: &apiclient.ManifestResponse{ - Manifests: []string{}, + Manifests: []*apiclient.Manifest{}, Namespace: test.FakeDestNamespace, Server: test.FakeClusterURL, Revision: "abc123", @@ -1821,7 +1847,7 @@ func TestCompareAppStateRevisionUpdatedWithHelmSource(t *testing.T) { app := newFakeMultiSourceApp() data := fakeData{ manifestResponse: &apiclient.ManifestResponse{ - Manifests: []string{}, + Manifests: []*apiclient.Manifest{}, Namespace: test.FakeDestNamespace, Server: test.FakeClusterURL, Revision: "abc123", diff --git a/controller/sync.go b/controller/sync.go index 3f21b79caa861..90b2ccdf9e57e 100644 --- a/controller/sync.go +++ b/controller/sync.go @@ -107,6 +107,8 @@ func (m *appStateManager) SyncAppState(app *v1alpha1.Application, state *v1alpha var sources []v1alpha1.ApplicationSource revisions := make([]string, 0) + logCtx := log.WithField("application", app.Name) + if state.Operation.Sync == nil { state.Phase = common.OperationFailed state.Message = "Invalid operation request: no operation specified" @@ -150,6 +152,7 @@ func (m *appStateManager) SyncAppState(app *v1alpha1.Application, state *v1alpha syncRes = state.SyncResult revision = state.SyncResult.Revision revisions = append(revisions, state.SyncResult.Revisions...) + logCtx.Infof("Resuming sync operation to revision %s", revision) } else { syncRes = &v1alpha1.SyncOperationResult{} // status.operationState.syncResult.source. must be set properly since auto-sync relies @@ -172,6 +175,7 @@ func (m *appStateManager) SyncAppState(app *v1alpha1.Application, state *v1alpha } } else { if revision == "" { + logCtx.Infof("No previous sync state found, revision is empty. Take revision from operation \"%s\"", syncOp.Revision) revision = syncOp.Revision } } @@ -410,6 +414,7 @@ func (m *appStateManager) SyncAppState(app *v1alpha1.Application, state *v1alpha if state.Phase == common.OperationTerminating { syncCtx.Terminate() } else { + logEntry.Infof("Starting sync operation for revision \"%s\"", compareResult.syncStatus.Revision) syncCtx.Sync() } var resState []common.ResourceSyncResult diff --git a/controller/sync_test.go b/controller/sync_test.go index 5560ffc2ec971..2951f0411fd34 100644 --- a/controller/sync_test.go +++ b/controller/sync_test.go @@ -37,7 +37,7 @@ func TestPersistRevisionHistory(t *testing.T) { data := fakeData{ apps: []runtime.Object{app, defaultProject}, manifestResponse: &apiclient.ManifestResponse{ - Manifests: []string{}, + Manifests: []*apiclient.Manifest{}, Namespace: test.FakeDestNamespace, Server: test.FakeClusterURL, Revision: "abc123", @@ -83,7 +83,7 @@ func TestPersistManagedNamespaceMetadataState(t *testing.T) { data := fakeData{ apps: []runtime.Object{app, defaultProject}, manifestResponse: &apiclient.ManifestResponse{ - Manifests: []string{}, + Manifests: []*apiclient.Manifest{}, Namespace: test.FakeDestNamespace, Server: test.FakeClusterURL, Revision: "abc123", @@ -114,7 +114,7 @@ func TestPersistRevisionHistoryRollback(t *testing.T) { data := fakeData{ apps: []runtime.Object{app, defaultProject}, manifestResponse: &apiclient.ManifestResponse{ - Manifests: []string{}, + Manifests: []*apiclient.Manifest{}, Namespace: test.FakeDestNamespace, Server: test.FakeClusterURL, Revision: "abc123", @@ -167,7 +167,7 @@ func TestSyncComparisonError(t *testing.T) { data := fakeData{ apps: []runtime.Object{app, defaultProject}, manifestResponse: &apiclient.ManifestResponse{ - Manifests: []string{}, + Manifests: []*apiclient.Manifest{}, Namespace: test.FakeDestNamespace, Server: test.FakeClusterURL, Revision: "abc123", @@ -213,7 +213,7 @@ func TestAppStateManager_SyncAppState(t *testing.T) { data := fakeData{ apps: []runtime.Object{app, project}, manifestResponse: &apiclient.ManifestResponse{ - Manifests: []string{}, + Manifests: []*apiclient.Manifest{}, Namespace: test.FakeDestNamespace, Server: test.FakeClusterURL, Revision: "abc123", @@ -288,7 +288,7 @@ func TestSyncWindowDeniesSync(t *testing.T) { data := fakeData{ apps: []runtime.Object{app, project}, manifestResponse: &apiclient.ManifestResponse{ - Manifests: []string{}, + Manifests: []*apiclient.Manifest{}, Namespace: test.FakeDestNamespace, Server: test.FakeClusterURL, Revision: "abc123", @@ -1307,7 +1307,7 @@ func TestSyncWithImpersonate(t *testing.T) { data := fakeData{ apps: []runtime.Object{app, project}, manifestResponse: &apiclient.ManifestResponse{ - Manifests: []string{}, + Manifests: []*apiclient.Manifest{}, Namespace: test.FakeDestNamespace, Server: "https://localhost:6443", Revision: "abc123", diff --git a/docs/operator-manual/server-commands/argocd-repo-server.md b/docs/operator-manual/server-commands/argocd-repo-server.md index 12e4d34d14028..9fe3bebd8d0b6 100644 --- a/docs/operator-manual/server-commands/argocd-repo-server.md +++ b/docs/operator-manual/server-commands/argocd-repo-server.md @@ -17,6 +17,11 @@ argocd-repo-server [flags] ``` --address string Listen on given address for incoming connections (default "0.0.0.0") --allow-oob-symlinks Allow out-of-bounds symlinks in repositories (not recommended) + --cf-app-config-cache-expiration duration Cache expiration for Codefresh application configs (default 3m0s) + --codefresh-application-version-enabled Allow Codefresh application versioning (default true) + --codefresh-application-version-use-appconfig Allow getting application configuration from the Codefresh API (default true) + --codefresh-token string Codefresh token + --codefresh-url string Codefresh API URL (default "https://g.codefresh.io") --default-cache-expiration duration Cache expiration default (default 24h0m0s) --disable-helm-manifest-max-extracted-size Disable maximum size of helm manifest archives when extracted --disable-tls Disable TLS on the gRPC endpoint diff --git a/docs/operator-manual/server-commands/argocd-server.md b/docs/operator-manual/server-commands/argocd-server.md index fe284a5940733..5e9903eba8751 100644 --- a/docs/operator-manual/server-commands/argocd-server.md +++ b/docs/operator-manual/server-commands/argocd-server.md @@ -38,6 +38,7 @@ argocd-server [flags] --as-uid string UID to impersonate for the operation --basehref string Value for base href in index.html. Used if Argo CD is running behind reverse proxy under subpath different from / (default "/") --certificate-authority string Path to a cert file for the certificate authority + --cf-app-config-cache-expiration duration Cache expiration for Codefresh application configs (default 3m0s) --client-certificate string Path to a client certificate file for TLS --client-key string Path to a client key file for TLS --cluster string The name of the kubeconfig cluster to use diff --git a/event_reporter/application/client.go b/event_reporter/application/client.go new file mode 100644 index 0000000000000..aa367a7fb7779 --- /dev/null +++ b/event_reporter/application/client.go @@ -0,0 +1,188 @@ +package application + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "strings" + "time" + + "google.golang.org/grpc" + + appclient "github.com/argoproj/argo-cd/v2/pkg/apiclient/application" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + repoapiclient "github.com/argoproj/argo-cd/v2/reposerver/apiclient" +) + +type ApplicationClient interface { + Get(ctx context.Context, in *appclient.ApplicationQuery, opts ...grpc.CallOption) (*v1alpha1.Application, error) + + RevisionMetadata(ctx context.Context, in *appclient.RevisionMetadataQuery, opts ...grpc.CallOption) (*v1alpha1.RevisionMetadata, error) + + GetManifests(ctx context.Context, in *appclient.ApplicationManifestQuery, opts ...grpc.CallOption) (*repoapiclient.ManifestResponse, error) + + ResourceTree(ctx context.Context, in *appclient.ResourcesQuery, opts ...grpc.CallOption) (*v1alpha1.ApplicationTree, error) + + GetResource(ctx context.Context, in *appclient.ApplicationResourceRequest, opts ...grpc.CallOption) (*appclient.ApplicationResourceResponse, error) + + List(ctx context.Context, in *appclient.ApplicationQuery, opts ...grpc.CallOption) (*v1alpha1.ApplicationList, error) +} + +type httpApplicationClient struct { + httpClient *http.Client + baseUrl string + token string + rootpath string +} + +func NewHttpApplicationClient(token string, address string, rootpath string) ApplicationClient { + if rootpath != "" && !strings.HasPrefix(rootpath, "/") { + rootpath = "/" + rootpath + } + + if !strings.Contains(address, "http") { + address = "http://" + address + } + + if rootpath != "" { + address = address + rootpath + } + + return &httpApplicationClient{ + httpClient: &http.Client{ + Timeout: 30 * time.Second, + }, + baseUrl: address, + token: token, + rootpath: rootpath, + } +} + +func (c *httpApplicationClient) execute(ctx context.Context, url string, result interface{}) error { + req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil) + if err != nil { + return err + } + + req.Header.Set("Content-Type", "application/json") + req.Header.Set("Authorization", "Bearer "+c.token) + + res, err := c.httpClient.Do(req) + if err != nil { + return err + } + defer res.Body.Close() + + b, _ := io.ReadAll(res.Body) + + isStatusOK := res.StatusCode >= 200 && res.StatusCode < 300 + if !isStatusOK { + return fmt.Errorf("argocd server respond with code %d, msg is: %s", res.StatusCode, string(b)) + } + + err = json.Unmarshal(b, &result) + if err != nil { + return err + } + return nil +} + +func (c *httpApplicationClient) Get(ctx context.Context, in *appclient.ApplicationQuery, opts ...grpc.CallOption) (*v1alpha1.Application, error) { + params := fmt.Sprintf("?appNamespace=%s", + *in.AppNamespace) + url := fmt.Sprintf("%s/api/v1/applications/%s%s", c.baseUrl, *in.Name, params) + application := &v1alpha1.Application{} + err := c.execute(ctx, url, application) + if err != nil { + return nil, err + } + return application, nil +} + +func (c *httpApplicationClient) RevisionMetadata(ctx context.Context, in *appclient.RevisionMetadataQuery, opts ...grpc.CallOption) (*v1alpha1.RevisionMetadata, error) { + params := fmt.Sprintf("?appNamespace=%s&project=%s", + *in.AppNamespace, + *in.Project) + if in.SourceIndex != nil { + params += fmt.Sprintf("&sourceIndex=%d", *in.SourceIndex) + } + url := fmt.Sprintf("%s/api/v1/applications/%s/revisions/%s/metadata%s", c.baseUrl, *in.Name, *in.Revision, params) + revisionMetadata := &v1alpha1.RevisionMetadata{} + err := c.execute(ctx, url, revisionMetadata) + if err != nil { + return nil, err + } + return revisionMetadata, nil +} + +func (c *httpApplicationClient) GetManifests(ctx context.Context, in *appclient.ApplicationManifestQuery, opts ...grpc.CallOption) (*repoapiclient.ManifestResponse, error) { + params := fmt.Sprintf("?appNamespace=%s&project=%s", + *in.AppNamespace, + *in.Project) + if in.Revision != nil { + params = fmt.Sprintf("%s&revision=%s", params, *in.Revision) + } + if len(in.SourcePositions) > 0 { + for _, sourcePosition := range in.SourcePositions { + params = fmt.Sprintf("%s&sourcePositions=%d", params, sourcePosition) + } + } + if len(in.Revisions) > 0 { + for _, revision := range in.Revisions { + params = fmt.Sprintf("%s&revisions=%s", params, revision) + } + } + url := fmt.Sprintf("%s/api/v1/applications/%s/manifests%s", c.baseUrl, *in.Name, params) + + manifest := &repoapiclient.ManifestResponse{} + err := c.execute(ctx, url, manifest) + if err != nil { + return nil, err + } + return manifest, nil +} + +func (c *httpApplicationClient) ResourceTree(ctx context.Context, in *appclient.ResourcesQuery, opts ...grpc.CallOption) (*v1alpha1.ApplicationTree, error) { + params := fmt.Sprintf("?appNamespace=%s&project=%s", + *in.AppNamespace, + *in.Project) + url := fmt.Sprintf("%s/api/v1/applications/%s/resource-tree%s", c.baseUrl, *in.ApplicationName, params) + tree := &v1alpha1.ApplicationTree{} + err := c.execute(ctx, url, tree) + if err != nil { + return nil, err + } + return tree, nil +} + +func (c *httpApplicationClient) GetResource(ctx context.Context, in *appclient.ApplicationResourceRequest, opts ...grpc.CallOption) (*appclient.ApplicationResourceResponse, error) { + params := fmt.Sprintf("?appNamespace=%s&namespace=%s&resourceName=%s&version=%s&group=%s&kind=%s&project=%s", + *in.AppNamespace, + *in.Namespace, + *in.ResourceName, + *in.Version, + *in.Group, + *in.Kind, + *in.Project) + url := fmt.Sprintf("%s/api/v1/applications/%s/resource%s", c.baseUrl, *in.Name, params) + + applicationResource := &appclient.ApplicationResourceResponse{} + err := c.execute(ctx, url, applicationResource) + if err != nil { + return nil, err + } + return applicationResource, nil +} + +func (c *httpApplicationClient) List(ctx context.Context, in *appclient.ApplicationQuery, opts ...grpc.CallOption) (*v1alpha1.ApplicationList, error) { + url := fmt.Sprintf("%s/api/v1/applications", c.baseUrl) + + apps := &v1alpha1.ApplicationList{} + err := c.execute(ctx, url, apps) + if err != nil { + return nil, err + } + return apps, nil +} diff --git a/event_reporter/application/mocks/ApplicationClient.go b/event_reporter/application/mocks/ApplicationClient.go new file mode 100644 index 0000000000000..e3115cbcdae34 --- /dev/null +++ b/event_reporter/application/mocks/ApplicationClient.go @@ -0,0 +1,257 @@ +// Code generated by mockery v2.43.2. DO NOT EDIT. + +package mocks + +import ( + application "github.com/argoproj/argo-cd/v2/pkg/apiclient/application" + apiclient "github.com/argoproj/argo-cd/v2/reposerver/apiclient" + + context "context" + + grpc "google.golang.org/grpc" + + mock "github.com/stretchr/testify/mock" + + v1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" +) + +// ApplicationClient is an autogenerated mock type for the ApplicationClient type +type ApplicationClient struct { + mock.Mock +} + +// Get provides a mock function with given fields: ctx, in, opts +func (_m *ApplicationClient) Get(ctx context.Context, in *application.ApplicationQuery, opts ...grpc.CallOption) (*v1alpha1.Application, error) { + _va := make([]interface{}, len(opts)) + for _i := range opts { + _va[_i] = opts[_i] + } + var _ca []interface{} + _ca = append(_ca, ctx, in) + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + if len(ret) == 0 { + panic("no return value specified for Get") + } + + var r0 *v1alpha1.Application + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *application.ApplicationQuery, ...grpc.CallOption) (*v1alpha1.Application, error)); ok { + return rf(ctx, in, opts...) + } + if rf, ok := ret.Get(0).(func(context.Context, *application.ApplicationQuery, ...grpc.CallOption) *v1alpha1.Application); ok { + r0 = rf(ctx, in, opts...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*v1alpha1.Application) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *application.ApplicationQuery, ...grpc.CallOption) error); ok { + r1 = rf(ctx, in, opts...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetManifests provides a mock function with given fields: ctx, in, opts +func (_m *ApplicationClient) GetManifests(ctx context.Context, in *application.ApplicationManifestQuery, opts ...grpc.CallOption) (*apiclient.ManifestResponse, error) { + _va := make([]interface{}, len(opts)) + for _i := range opts { + _va[_i] = opts[_i] + } + var _ca []interface{} + _ca = append(_ca, ctx, in) + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + if len(ret) == 0 { + panic("no return value specified for GetManifests") + } + + var r0 *apiclient.ManifestResponse + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *application.ApplicationManifestQuery, ...grpc.CallOption) (*apiclient.ManifestResponse, error)); ok { + return rf(ctx, in, opts...) + } + if rf, ok := ret.Get(0).(func(context.Context, *application.ApplicationManifestQuery, ...grpc.CallOption) *apiclient.ManifestResponse); ok { + r0 = rf(ctx, in, opts...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*apiclient.ManifestResponse) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *application.ApplicationManifestQuery, ...grpc.CallOption) error); ok { + r1 = rf(ctx, in, opts...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetResource provides a mock function with given fields: ctx, in, opts +func (_m *ApplicationClient) GetResource(ctx context.Context, in *application.ApplicationResourceRequest, opts ...grpc.CallOption) (*application.ApplicationResourceResponse, error) { + _va := make([]interface{}, len(opts)) + for _i := range opts { + _va[_i] = opts[_i] + } + var _ca []interface{} + _ca = append(_ca, ctx, in) + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + if len(ret) == 0 { + panic("no return value specified for GetResource") + } + + var r0 *application.ApplicationResourceResponse + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *application.ApplicationResourceRequest, ...grpc.CallOption) (*application.ApplicationResourceResponse, error)); ok { + return rf(ctx, in, opts...) + } + if rf, ok := ret.Get(0).(func(context.Context, *application.ApplicationResourceRequest, ...grpc.CallOption) *application.ApplicationResourceResponse); ok { + r0 = rf(ctx, in, opts...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*application.ApplicationResourceResponse) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *application.ApplicationResourceRequest, ...grpc.CallOption) error); ok { + r1 = rf(ctx, in, opts...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// List provides a mock function with given fields: ctx, in, opts +func (_m *ApplicationClient) List(ctx context.Context, in *application.ApplicationQuery, opts ...grpc.CallOption) (*v1alpha1.ApplicationList, error) { + _va := make([]interface{}, len(opts)) + for _i := range opts { + _va[_i] = opts[_i] + } + var _ca []interface{} + _ca = append(_ca, ctx, in) + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + if len(ret) == 0 { + panic("no return value specified for List") + } + + var r0 *v1alpha1.ApplicationList + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *application.ApplicationQuery, ...grpc.CallOption) (*v1alpha1.ApplicationList, error)); ok { + return rf(ctx, in, opts...) + } + if rf, ok := ret.Get(0).(func(context.Context, *application.ApplicationQuery, ...grpc.CallOption) *v1alpha1.ApplicationList); ok { + r0 = rf(ctx, in, opts...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*v1alpha1.ApplicationList) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *application.ApplicationQuery, ...grpc.CallOption) error); ok { + r1 = rf(ctx, in, opts...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ResourceTree provides a mock function with given fields: ctx, in, opts +func (_m *ApplicationClient) ResourceTree(ctx context.Context, in *application.ResourcesQuery, opts ...grpc.CallOption) (*v1alpha1.ApplicationTree, error) { + _va := make([]interface{}, len(opts)) + for _i := range opts { + _va[_i] = opts[_i] + } + var _ca []interface{} + _ca = append(_ca, ctx, in) + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + if len(ret) == 0 { + panic("no return value specified for ResourceTree") + } + + var r0 *v1alpha1.ApplicationTree + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *application.ResourcesQuery, ...grpc.CallOption) (*v1alpha1.ApplicationTree, error)); ok { + return rf(ctx, in, opts...) + } + if rf, ok := ret.Get(0).(func(context.Context, *application.ResourcesQuery, ...grpc.CallOption) *v1alpha1.ApplicationTree); ok { + r0 = rf(ctx, in, opts...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*v1alpha1.ApplicationTree) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *application.ResourcesQuery, ...grpc.CallOption) error); ok { + r1 = rf(ctx, in, opts...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// RevisionMetadata provides a mock function with given fields: ctx, in, opts +func (_m *ApplicationClient) RevisionMetadata(ctx context.Context, in *application.RevisionMetadataQuery, opts ...grpc.CallOption) (*v1alpha1.RevisionMetadata, error) { + _va := make([]interface{}, len(opts)) + for _i := range opts { + _va[_i] = opts[_i] + } + var _ca []interface{} + _ca = append(_ca, ctx, in) + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + if len(ret) == 0 { + panic("no return value specified for RevisionMetadata") + } + + var r0 *v1alpha1.RevisionMetadata + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *application.RevisionMetadataQuery, ...grpc.CallOption) (*v1alpha1.RevisionMetadata, error)); ok { + return rf(ctx, in, opts...) + } + if rf, ok := ret.Get(0).(func(context.Context, *application.RevisionMetadataQuery, ...grpc.CallOption) *v1alpha1.RevisionMetadata); ok { + r0 = rf(ctx, in, opts...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*v1alpha1.RevisionMetadata) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *application.RevisionMetadataQuery, ...grpc.CallOption) error); ok { + r1 = rf(ctx, in, opts...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// NewApplicationClient creates a new instance of ApplicationClient. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewApplicationClient(t interface { + mock.TestingT + Cleanup(func()) +}) *ApplicationClient { + mock := &ApplicationClient{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/event_reporter/controller/controller.go b/event_reporter/controller/controller.go new file mode 100644 index 0000000000000..c84794da53628 --- /dev/null +++ b/event_reporter/controller/controller.go @@ -0,0 +1,133 @@ +package controller + +import ( + "context" + "math" + "strings" + "time" + + "github.com/argoproj/argo-cd/v2/pkg/sources_server_client" + + "github.com/argoproj/argo-cd/v2/util/db" + + appclient "github.com/argoproj/argo-cd/v2/event_reporter/application" + + log "github.com/sirupsen/logrus" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" + + argocommon "github.com/argoproj/argo-cd/v2/common" + "github.com/argoproj/argo-cd/v2/event_reporter/metrics" + "github.com/argoproj/argo-cd/v2/event_reporter/reporter" + appv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + applisters "github.com/argoproj/argo-cd/v2/pkg/client/listers/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/pkg/codefresh" + servercache "github.com/argoproj/argo-cd/v2/server/cache" + argoutil "github.com/argoproj/argo-cd/v2/util/argo" + "github.com/argoproj/argo-cd/v2/util/env" + "github.com/argoproj/argo-cd/v2/util/settings" +) + +var ( + watchAPIBufferSize = 1000 + applicationEventCacheExpiration = time.Minute * time.Duration(env.ParseNumFromEnv(argocommon.EnvApplicationEventCacheDuration, 20, 0, math.MaxInt32)) +) + +type EventReporterController interface { + Run(ctx context.Context) +} + +type eventReporterController struct { + settingsMgr *settings.SettingsManager + appBroadcaster reporter.Broadcaster + applicationEventReporter reporter.ApplicationEventReporter + cache *servercache.Cache + appLister applisters.ApplicationLister + applicationServiceClient appclient.ApplicationClient + metricsServer *metrics.MetricsServer +} + +func NewEventReporterController(appInformer cache.SharedIndexInformer, cache *servercache.Cache, settingsMgr *settings.SettingsManager, applicationServiceClient appclient.ApplicationClient, appLister applisters.ApplicationLister, codefreshConfig *codefresh.CodefreshConfig, metricsServer *metrics.MetricsServer, featureManager *reporter.FeatureManager, rateLimiterOpts *reporter.RateLimiterOpts, db db.ArgoDB, useSourcesServer bool, sourcesServerConfig *sources_server_client.SourcesServerConfig) EventReporterController { + appBroadcaster := reporter.NewBroadcaster(featureManager, metricsServer, rateLimiterOpts) + _, err := appInformer.AddEventHandler(appBroadcaster) + if err != nil { + log.Error(err) + } + return &eventReporterController{ + appBroadcaster: appBroadcaster, + applicationEventReporter: reporter.NewApplicationEventReporter(cache, applicationServiceClient, appLister, codefreshConfig, metricsServer, db, useSourcesServer, sourcesServerConfig), + cache: cache, + settingsMgr: settingsMgr, + applicationServiceClient: applicationServiceClient, + appLister: appLister, + metricsServer: metricsServer, + } +} + +func (c *eventReporterController) Run(ctx context.Context) { + var logCtx log.FieldLogger = log.StandardLogger() + + // sendIfPermitted is a helper to send the application to the client's streaming channel if the + // caller has RBAC privileges permissions to view it + sendIfPermitted := func(ctx context.Context, a appv1.Application, eventType watch.EventType, eventProcessingStartedAt string, ignoreResourceCache bool) error { + if eventType == watch.Bookmark { + return nil // ignore this event + } + + appInstanceLabelKey, err := c.settingsMgr.GetAppInstanceLabelKey() + if err != nil { + return err + } + installationID, err := c.settingsMgr.GetInstallationID() + if err != nil { + return err + } + trackingMethod := argoutil.GetTrackingMethod(c.settingsMgr) + + err = c.applicationEventReporter.StreamApplicationEvents(ctx, &a, eventProcessingStartedAt, ignoreResourceCache, &reporter.ArgoTrackingMetadata{ + AppInstanceLabelKey: &appInstanceLabelKey, + TrackingMethod: &trackingMethod, + InstallationID: &installationID, + }) + if err != nil { + return err + } + + if err := c.cache.SetLastApplicationEvent(&a, applicationEventCacheExpiration); err != nil { + logCtx.WithError(err).Error("failed to cache last sent application event") + return err + } + return nil + } + + // TODO: move to abstraction + eventsChannel := make(chan *appv1.ApplicationWatchEvent, watchAPIBufferSize) + unsubscribe := c.appBroadcaster.Subscribe(eventsChannel) + defer unsubscribe() + for { + select { + case <-ctx.Done(): + return + case event := <-eventsChannel: + logCtx.Infof("channel size is %d", len(eventsChannel)) + c.metricsServer.SetQueueSizeGauge(len(eventsChannel)) + shouldProcess, ignoreResourceCache := c.applicationEventReporter.ShouldSendApplicationEvent(event) + if !shouldProcess { + logCtx.Infof("Skipping event %s/%s", event.Application.Name, event.Type) + c.metricsServer.IncCachedIgnoredEventsCounter(metrics.MetricAppEventType, event.Application.Name) + continue + } + eventProcessingStartedAt := time.Now().Format("2006-01-02T15:04:05.000Z") + ctx, cancel := context.WithTimeout(ctx, 2*time.Minute) + err := sendIfPermitted(ctx, event.Application, event.Type, eventProcessingStartedAt, ignoreResourceCache) + if err != nil { + logCtx.WithError(err).Error("failed to stream application events") + if strings.Contains(err.Error(), "context deadline exceeded") { + logCtx.Info("Closing event-source connection") + cancel() + } + } + cancel() + } + } +} diff --git a/event_reporter/grafana-dashboard.json b/event_reporter/grafana-dashboard.json new file mode 100644 index 0000000000000..1c43c1049b7da --- /dev/null +++ b/event_reporter/grafana-dashboard.json @@ -0,0 +1,1364 @@ +{ + "__inputs": [ + { + "name": "DS_MIMIR_(PRODUCTION PERMANENT RETENTION)", + "label": "Mimir (Production permanent retention)", + "description": "", + "type": "datasource", + "pluginId": "prometheus", + "pluginName": "Prometheus" + } + ], + "__elements": {}, + "__requires": [ + { + "type": "grafana", + "id": "grafana", + "name": "Grafana", + "version": "11.0.0" + }, + { + "type": "panel", + "id": "heatmap", + "name": "Heatmap", + "version": "" + }, + { + "type": "datasource", + "id": "prometheus", + "name": "Prometheus", + "version": "1.0.0" + }, + { + "type": "panel", + "id": "timeseries", + "name": "Time series", + "version": "" + } + ], + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": { + "type": "datasource", + "uid": "grafana" + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 1, + "id": null, + "links": [], + "liveNow": false, + "panels": [ + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 49, + "panels": [], + "title": "General stats", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_MIMIR_(PRODUCTION PERMANENT RETENTION)}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "opacity", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "line" + } + }, + "mappings": [], + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "transparent", + "value": null + }, + { + "color": "orange", + "value": 400 + }, + { + "color": "red", + "value": 800 + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 9, + "w": 24, + "x": 0, + "y": 1 + }, + "id": 54, + "options": { + "legend": { + "calcs": [ + "mean", + "max" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true, + "sortBy": "Mean", + "sortDesc": true + }, + "tooltip": { + "maxHeight": 600, + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "10.1.5", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_MIMIR_(PRODUCTION PERMANENT RETENTION)}" + }, + "disableTextWrap": false, + "editorMode": "code", + "expr": "sum(\n codefresh_event_reporter_queue_size\n {reporter_shard=~\"$reporter_shard\", namespace=~\"$runtime\"}\n) by(reporter_shard)", + "format": "time_series", + "fullMetaSearch": false, + "includeNullMetadata": true, + "interval": "$resolution", + "intervalFactor": 1, + "legendFormat": "__auto", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "Queue size", + "transformations": [ + { + "id": "renameByRegex", + "options": { + "regex": "(\\d+)", + "renamePattern": "shard $1" + } + } + ], + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_MIMIR_(PRODUCTION PERMANENT RETENTION)}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "opacity", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "eps" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 24, + "x": 0, + "y": 10 + }, + "id": 58, + "options": { + "legend": { + "calcs": [ + "mean", + "max" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true, + "sortBy": "Mean", + "sortDesc": true + }, + "tooltip": { + "maxHeight": 600, + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "10.1.5", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_MIMIR_(PRODUCTION PERMANENT RETENTION)}" + }, + "disableTextWrap": false, + "editorMode": "code", + "expr": "sum(\n rate(\n codefresh_event_reporter_enqueued_events_total\n {reporter_shard=~\"$reporter_shard\", namespace=\"$runtime\"}\n [$__rate_interval])\n) by(${group_by:csv})", + "format": "time_series", + "fullMetaSearch": false, + "includeNullMetadata": true, + "interval": "$resolution", + "intervalFactor": 1, + "legendFormat": "__auto", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "Events enqueued", + "transformations": [ + { + "id": "renameByRegex", + "options": { + "regex": "(\\d+)", + "renamePattern": "shard $1" + } + } + ], + "type": "timeseries" + }, + { + "collapsed": false, + "datasource": { + "uid": "$datasource" + }, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 18 + }, + "id": 4, + "panels": [], + "targets": [ + { + "datasource": { + "uid": "$datasource" + }, + "refId": "A" + } + ], + "title": "Events stats", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_MIMIR_(PRODUCTION PERMANENT RETENTION)}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "opacity", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "s" + }, + "overrides": [] + }, + "gridPos": { + "h": 9, + "w": 24, + "x": 0, + "y": 19 + }, + "id": 52, + "options": { + "legend": { + "calcs": [ + "mean", + "max" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true, + "sortBy": "Mean", + "sortDesc": true + }, + "tooltip": { + "maxHeight": 600, + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "10.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_MIMIR_(PRODUCTION PERMANENT RETENTION)}" + }, + "disableTextWrap": false, + "editorMode": "code", + "expr": "sum(\n rate(\n codefresh_event_reporter_event_processing_duration_sum\n {reporter_shard=~\"$reporter_shard\", namespace=~\"$runtime\"}\n [$__rate_interval])\n) by(${group_by:csv})\n/\nsum(\n rate(\n codefresh_event_reporter_event_processing_duration_count\n {reporter_shard=~\"$reporter_shard\", namespace=~\"$runtime\"}\n [$__rate_interval])\n) by(${group_by:csv})", + "format": "time_series", + "fullMetaSearch": false, + "hide": false, + "includeNullMetadata": true, + "interval": "$resolution", + "intervalFactor": 1, + "legendFormat": "__auto", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "Average processing time", + "transformations": [ + { + "id": "renameByRegex", + "options": { + "regex": "(\\d+)", + "renamePattern": "shard $1" + } + } + ], + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_MIMIR_(PRODUCTION PERMANENT RETENTION)}" + }, + "description": "Dropped due to one of:\n- rate limited\n- queue overflow", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "opacity", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "eps" + }, + "overrides": [] + }, + "gridPos": { + "h": 9, + "w": 24, + "x": 0, + "y": 28 + }, + "id": 47, + "options": { + "legend": { + "calcs": [ + "mean", + "max" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true, + "sortBy": "Mean", + "sortDesc": true + }, + "tooltip": { + "maxHeight": 600, + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "10.1.5", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_MIMIR_(PRODUCTION PERMANENT RETENTION)}" + }, + "disableTextWrap": false, + "editorMode": "code", + "expr": "sum (\n rate(\n codefresh_event_reporter_dropped_events_total\n {reporter_shard=~\"$reporter_shard\", namespace=~\"$runtime\"}\n [$__rate_interval])\n) by(${group_by:csv})\n> 0", + "format": "time_series", + "fullMetaSearch": false, + "includeNullMetadata": true, + "interval": "$resolution", + "intervalFactor": 1, + "legendFormat": "__auto", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "Dropped events", + "transformations": [ + { + "id": "renameByRegex", + "options": { + "regex": "(\\d+)", + "renamePattern": "shard $1" + } + } + ], + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_MIMIR_(PRODUCTION PERMANENT RETENTION)}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "opacity", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "eps" + }, + "overrides": [] + }, + "gridPos": { + "h": 9, + "w": 24, + "x": 0, + "y": 37 + }, + "id": 59, + "options": { + "legend": { + "calcs": [ + "mean", + "max" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true, + "sortBy": "Mean", + "sortDesc": true + }, + "tooltip": { + "maxHeight": 600, + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "10.1.5", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_MIMIR_(PRODUCTION PERMANENT RETENTION)}" + }, + "disableTextWrap": false, + "editorMode": "code", + "expr": "sum (\n rate(\n codefresh_event_reporter_errored_events_total\n {reporter_shard=~\"$reporter_shard\", namespace=~\"$runtime\"}\n [$__rate_interval])\n) by(${group_by:csv})\n> 0", + "format": "time_series", + "fullMetaSearch": false, + "includeNullMetadata": true, + "interval": "$resolution", + "intervalFactor": 1, + "legendFormat": "__auto", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "Errored events", + "transformations": [ + { + "id": "renameByRegex", + "options": { + "regex": "(\\d+)", + "renamePattern": "shard $1" + } + } + ], + "type": "timeseries" + }, + { + "collapsed": true, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 46 + }, + "id": 51, + "panels": [ + { + "cards": {}, + "color": { + "cardColor": "#b4ff00", + "colorScale": "sqrt", + "colorScheme": "interpolateSpectral", + "exponent": 0.5, + "mode": "spectrum" + }, + "dataFormat": "tsbuckets", + "datasource": { + "type": "prometheus", + "uid": "${DS_MIMIR_(PRODUCTION PERMANENT RETENTION)}" + }, + "fieldConfig": { + "defaults": { + "custom": { + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "scaleDistribution": { + "type": "linear" + } + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 24, + "x": 0, + "y": 47 + }, + "heatmap": {}, + "hideZeroBuckets": false, + "highlightCards": true, + "id": 44, + "interval": "$resolution", + "legend": { + "show": false + }, + "options": { + "calculate": false, + "calculation": {}, + "cellGap": 2, + "cellValues": {}, + "color": { + "exponent": 0.5, + "fill": "#b4ff00", + "mode": "scheme", + "reverse": false, + "scale": "exponential", + "scheme": "Spectral", + "steps": 128 + }, + "exemplars": { + "color": "rgba(255,0,255,0.7)" + }, + "filterValues": { + "le": 1e-9 + }, + "legend": { + "show": true + }, + "rowsFrame": { + "layout": "auto" + }, + "showValue": "never", + "tooltip": { + "mode": "single", + "showColorScale": false, + "yHistogram": false + }, + "yAxis": { + "axisPlacement": "left", + "reverse": false, + "unit": "s" + } + }, + "pluginVersion": "10.4.0", + "reverseYBuckets": false, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_MIMIR_(PRODUCTION PERMANENT RETENTION)}" + }, + "disableTextWrap": false, + "editorMode": "code", + "expr": "sum(\n rate(\n codefresh_event_reporter_event_processing_duration_bucket\n {reporter_shard=~\"$reporter_shard\", namespace=~\"$runtime\"}\n [$__rate_interval])\n) by(le) ", + "format": "heatmap", + "fullMetaSearch": false, + "hide": false, + "includeNullMetadata": true, + "interval": "$resolution", + "intervalFactor": 1, + "legendFormat": "__auto", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "App event performance", + "tooltip": { + "show": true, + "showHistogram": false + }, + "type": "heatmap", + "xAxis": { + "show": true + }, + "yAxis": { + "format": "short", + "logBase": 1, + "show": true + }, + "yBucketBound": "auto" + } + ], + "title": "Processing performance", + "type": "row" + }, + { + "collapsed": true, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 47 + }, + "id": 50, + "panels": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_MIMIR_(PRODUCTION PERMANENT RETENTION)}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "opacity", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "bytes" + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 55 + }, + "id": 12, + "options": { + "legend": { + "calcs": [ + "mean", + "max" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true, + "sortBy": "Mean", + "sortDesc": true + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "10.1.5", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_MIMIR_(PRODUCTION PERMANENT RETENTION)}" + }, + "disableTextWrap": false, + "editorMode": "code", + "expr": "sum(\n go_memstats_heap_alloc_bytes\n {namespace=~\"$runtime\", pod=~\"argo-cd-event-reporter-$reporter_shard.+\"}\n) by(pod)", + "format": "time_series", + "fullMetaSearch": false, + "includeNullMetadata": true, + "interval": "$resolution", + "intervalFactor": 1, + "legendFormat": "__auto", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "Memory Used", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_MIMIR_(PRODUCTION PERMANENT RETENTION)}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "opacity", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 62 + }, + "id": 45, + "options": { + "legend": { + "calcs": [ + "mean", + "max" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true, + "sortBy": "Mean", + "sortDesc": true + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "10.1.5", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_MIMIR_(PRODUCTION PERMANENT RETENTION)}" + }, + "disableTextWrap": false, + "editorMode": "code", + "expr": "sum(\n go_goroutines\n {namespace=~\"$runtime\", pod=~\"argo-cd-event-reporter-$reporter_shard.+\"}\n) by(pod)", + "format": "time_series", + "fullMetaSearch": false, + "includeNullMetadata": true, + "interval": "$resolution", + "intervalFactor": 1, + "legendFormat": "__auto", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "Number of go routines", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_MIMIR_(PRODUCTION PERMANENT RETENTION)}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "opacity", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 69 + }, + "id": 46, + "options": { + "legend": { + "calcs": [ + "mean", + "max" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true, + "sortBy": "Mean", + "sortDesc": true + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "10.1.5", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_MIMIR_(PRODUCTION PERMANENT RETENTION)}" + }, + "disableTextWrap": false, + "editorMode": "code", + "expr": "sum(\n go_threads\n {namespace=~\"$runtime\", pod=~\"argo-cd-event-reporter-$reporter_shard.+\"}\n) by(pod)", + "format": "time_series", + "fullMetaSearch": false, + "includeNullMetadata": true, + "interval": "$resolution", + "intervalFactor": 1, + "legendFormat": "__auto", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "Number of OS threads created", + "type": "timeseries" + } + ], + "title": "Go stats", + "type": "row" + } + ], + "refresh": "5m", + "schemaVersion": 39, + "tags": [], + "templating": { + "list": [ + { + "current": { + "selected": false, + "text": "Mimir (Production permanent retention)", + "value": "Mimir" + }, + "definition": "datasource(prometheus)", + "description": "rollout datasource", + "hide": 0, + "includeAll": false, + "label": "Datasource", + "multi": false, + "name": "datasource", + "options": [], + "query": "prometheus", + "queryValue": "", + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "type": "datasource" + }, + { + "current": {}, + "datasource": { + "type": "prometheus", + "uid": "${DS_MIMIR_(PRODUCTION PERMANENT RETENTION)}" + }, + "definition": "label_values(codefresh_event_reporter_queue_size,namespace)", + "hide": 0, + "includeAll": false, + "label": "Runtime", + "multi": false, + "name": "runtime", + "options": [], + "query": { + "qryType": 1, + "query": "label_values(codefresh_event_reporter_queue_size,namespace)", + "refId": "PrometheusVariableQueryEditor-VariableQuery" + }, + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "sort": 0, + "type": "query" + }, + { + "allValue": "", + "current": {}, + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "definition": "label_values(codefresh_event_reporter_queue_size,reporter_shard)", + "description": "Reporter shard number", + "hide": 0, + "includeAll": true, + "label": "Shard Number", + "multi": true, + "name": "reporter_shard", + "options": [], + "query": { + "qryType": 1, + "query": "label_values(codefresh_event_reporter_queue_size,reporter_shard)", + "refId": "PrometheusVariableQueryEditor-VariableQuery" + }, + "refresh": 2, + "regex": "", + "skipUrlSync": false, + "sort": 3, + "tagValuesQuery": "", + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "current": { + "selected": false, + "text": "reporter_shard", + "value": "reporter_shard" + }, + "hide": 0, + "includeAll": false, + "label": "Group By", + "multi": false, + "name": "group_by", + "options": [ + { + "selected": true, + "text": "reporter_shard", + "value": "reporter_shard" + }, + { + "selected": false, + "text": "application", + "value": "application" + } + ], + "query": "reporter_shard, application", + "queryValue": "", + "skipUrlSync": false, + "type": "custom" + }, + { + "current": { + "selected": false, + "text": "1m", + "value": "1m" + }, + "hide": 0, + "includeAll": false, + "multi": false, + "name": "resolution", + "options": [ + { + "selected": false, + "text": "30s", + "value": "30s" + }, + { + "selected": true, + "text": "1m", + "value": "1m" + }, + { + "selected": false, + "text": "5m", + "value": "5m" + }, + { + "selected": false, + "text": "10m", + "value": "10m" + }, + { + "selected": false, + "text": "30m", + "value": "30m" + }, + { + "selected": false, + "text": "1h", + "value": "1h" + } + ], + "query": "30s, 1m, 5m, 10m, 30m, 1h", + "queryValue": "", + "skipUrlSync": false, + "type": "custom" + } + ] + }, + "time": { + "from": "now-3h", + "to": "now" + }, + "timeRangeUpdatedDuringEditOrView": false, + "timepicker": { + "refresh_intervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ], + "time_options": [ + "5m", + "15m", + "1h", + "6h", + "12h", + "24h", + "2d", + "7d", + "30d" + ] + }, + "timezone": "", + "title": "Codefresh argo-cd events reporter (v2)", + "uid": "c80f9007-2398-4f05-9a87-2b06586dddef", + "version": 73, + "weekStart": "" +} \ No newline at end of file diff --git a/event_reporter/handlers/handlers.go b/event_reporter/handlers/handlers.go new file mode 100644 index 0000000000000..f431f7e60f173 --- /dev/null +++ b/event_reporter/handlers/handlers.go @@ -0,0 +1,81 @@ +package handlers + +import ( + "encoding/json" + "net/http" + "strconv" + "strings" + + appclient "github.com/argoproj/argo-cd/v2/event_reporter/application" + "github.com/argoproj/argo-cd/v2/event_reporter/sharding" + applicationpkg "github.com/argoproj/argo-cd/v2/pkg/apiclient/application" +) + +type RequestHandlers struct { + ApplicationServiceClient appclient.ApplicationClient +} + +func GetRequestHandlers(applicationServiceClient appclient.ApplicationClient) *RequestHandlers { + return &RequestHandlers{ + ApplicationServiceClient: applicationServiceClient, + } +} + +// queryParams: []string{"shardings"} +// response JSON { "strategyName": { Distribution, //Apps } +func (rH *RequestHandlers) GetAppDistribution(w http.ResponseWriter, r *http.Request) { + type ShardingAlgorithmData struct { + Distribution map[string]int `json:"distribution"` + Apps map[string]int `json:"apps"` + } + response := map[string]ShardingAlgorithmData{} + + shardings := []string{""} + shardingsParam := r.URL.Query().Get("shardings") + if shardingsParam != "" { + shardings = strings.Split(shardingsParam, ",") + } + + apps, err := rH.ApplicationServiceClient.List(r.Context(), &applicationpkg.ApplicationQuery{}) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + + shardingInstance := sharding.NewSharding() + + for _, shardingAlgorithm := range shardings { + distributionMap := make(map[string]int) + appsMap := make(map[string]int) + distributionFunction := shardingInstance.GetDistributionFunction(shardingAlgorithm) + + for _, app := range apps.Items { + expectedShard := distributionFunction(&app) + distributionMap[strconv.Itoa(expectedShard)] += 1 + appsMap[app.QualifiedName()] = expectedShard + } + + shardingAlgorithmDisplayName := shardingAlgorithm + if shardingAlgorithm == "" { + shardingAlgorithmDisplayName = "default" + } + + response[shardingAlgorithmDisplayName] = ShardingAlgorithmData{ + Distribution: distributionMap, + Apps: appsMap, + } + } + + jsonBytes, err := json.Marshal(response) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + + w.Header().Set("Content-Type", "application/json") + _, err = w.Write(jsonBytes) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } +} diff --git a/event_reporter/metrics/metrics.go b/event_reporter/metrics/metrics.go new file mode 100644 index 0000000000000..bdf934dae2927 --- /dev/null +++ b/event_reporter/metrics/metrics.go @@ -0,0 +1,158 @@ +package metrics + +import ( + "fmt" + "net/http" + "strconv" + "time" + + "github.com/argoproj/argo-cd/v2/event_reporter/sharding" + + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promhttp" + + "github.com/argoproj/argo-cd/v2/util/profile" +) + +type MetricsServer struct { + *http.Server + shard string + + queueSizeGauge *prometheus.GaugeVec + + enqueuedEventsCounter *prometheus.CounterVec + droppedEventsCounter *prometheus.CounterVec + + erroredEventsCounter *prometheus.CounterVec + cachedIgnoredEventsCounter *prometheus.CounterVec + eventProcessingDurationHistogram *prometheus.HistogramVec +} + +type MetricEventType string + +const ( + MetricAppEventType MetricEventType = "app" + MetricParentAppEventType MetricEventType = "parent_app" + MetricChildAppEventType MetricEventType = "child_app" + MetricResourceEventType MetricEventType = "resource" +) + +type MetricEventErrorType string + +const ( + MetricEventDeliveryErrorType MetricEventErrorType = "delivery" + MetricEventGetPayloadErrorType MetricEventErrorType = "get_payload" + MetricEventUnknownErrorType MetricEventErrorType = "unknown" +) + +var ( + queueSizeGauge = prometheus.NewGaugeVec( + prometheus.GaugeOpts{ + Name: "codefresh_event_reporter_queue_size", + Help: "Size of application events queue of a particular shard.", + }, + []string{"reporter_shard"}, + ) + + enqueuedEventsCounter = prometheus.NewCounterVec( + prometheus.CounterOpts{ + Name: "codefresh_event_reporter_enqueued_events_total", + Help: "Amount of application events not accepted into the queue of a particular shard.", + }, + []string{"reporter_shard", "application", "error_in_learning_mode"}, + ) + + droppedEventsCounter = prometheus.NewCounterVec( + prometheus.CounterOpts{ + Name: "codefresh_event_reporter_dropped_events_total", + Help: "Amount of dropped application events queue of taken shard.", + }, + []string{"reporter_shard", "application", "error_in_learning_mode"}, + ) + + erroredEventsCounter = prometheus.NewCounterVec( + prometheus.CounterOpts{ + Name: "codefresh_event_reporter_errored_events_total", + Help: "Amount of application events not accepted into the queue of a particular shard.", + }, + []string{"reporter_shard", "metric_event_type", "error_type", "application"}, + ) + + eventProcessingDurationHistogram = prometheus.NewHistogramVec( + prometheus.HistogramOpts{ + Name: "codefresh_event_reporter_event_processing_duration", + Help: "Application event processing duration.", + Buckets: []float64{0.25, .5, 1, 2, 5, 10, 20}, + }, + []string{"reporter_shard", "application", "metric_event_type"}, + ) + + cachedIgnoredEventsCounter = prometheus.NewCounterVec( + prometheus.CounterOpts{ + Name: "codefresh_event_reporter_cached_ignored_events", + Help: "Total number of ignored events because of cache.", + }, + []string{"reporter_shard", "metric_event_type", "application"}, + ) +) + +// NewMetricsServer returns a new prometheus server which collects api server metrics +func NewMetricsServer(host string, port int) *MetricsServer { + mux := http.NewServeMux() + registry := prometheus.NewRegistry() + + mux.Handle("/metrics", promhttp.HandlerFor(prometheus.Gatherers{ + registry, + prometheus.DefaultGatherer, + }, promhttp.HandlerOpts{})) + profile.RegisterProfiler(mux) + + registry.MustRegister(queueSizeGauge) + + registry.MustRegister(enqueuedEventsCounter) + registry.MustRegister(droppedEventsCounter) + registry.MustRegister(erroredEventsCounter) + + registry.MustRegister(cachedIgnoredEventsCounter) + registry.MustRegister(eventProcessingDurationHistogram) + + shard := sharding.GetShardNumber() + + return &MetricsServer{ + Server: &http.Server{ + Addr: fmt.Sprintf("%s:%d", host, port), + Handler: mux, + }, + shard: strconv.FormatInt(int64(shard), 10), + queueSizeGauge: queueSizeGauge, + enqueuedEventsCounter: enqueuedEventsCounter, + droppedEventsCounter: droppedEventsCounter, + erroredEventsCounter: erroredEventsCounter, + cachedIgnoredEventsCounter: cachedIgnoredEventsCounter, + eventProcessingDurationHistogram: eventProcessingDurationHistogram, + } +} + +func (m *MetricsServer) SetQueueSizeGauge(size int) { + m.queueSizeGauge.WithLabelValues(m.shard).Set(float64(size)) +} + +func (m *MetricsServer) IncEnqueuedEventsCounter(application string, errorInLearningMode bool) { + m.enqueuedEventsCounter.WithLabelValues(m.shard, application, strconv.FormatBool(errorInLearningMode)).Inc() +} + +func (m *MetricsServer) IncDroppedEventsCounter(application string, errorInLearningMode bool) { + m.droppedEventsCounter.WithLabelValues(m.shard, application, strconv.FormatBool(errorInLearningMode)).Inc() +} + +func (m *MetricsServer) IncErroredEventsCounter(metricEventType MetricEventType, errorType MetricEventErrorType, application string) { + m.erroredEventsCounter.WithLabelValues(m.shard, string(metricEventType), string(errorType), application).Inc() +} + +func (m *MetricsServer) IncCachedIgnoredEventsCounter(metricEventType MetricEventType, application string) { + m.cachedIgnoredEventsCounter.WithLabelValues(m.shard, string(metricEventType), application).Inc() +} + +func (m *MetricsServer) ObserveEventProcessingDurationHistogramDuration(application string, metricEventType MetricEventType, duration time.Duration) { + m.eventProcessingDurationHistogram.WithLabelValues(m.shard, application, string(metricEventType)).Observe(duration.Seconds()) +} diff --git a/event_reporter/metrics/utils/utils.go b/event_reporter/metrics/utils/utils.go new file mode 100644 index 0000000000000..bf9155a852b70 --- /dev/null +++ b/event_reporter/metrics/utils/utils.go @@ -0,0 +1,19 @@ +package metrics_utils + +import ( + "time" +) + +type MetricTimer struct { + startAt time.Time +} + +func NewMetricTimer() *MetricTimer { + return &MetricTimer{ + startAt: time.Now(), + } +} + +func (m *MetricTimer) Duration() time.Duration { + return time.Since(m.startAt) +} diff --git a/event_reporter/reporter/app_revision.go b/event_reporter/reporter/app_revision.go new file mode 100644 index 0000000000000..a930eeea0a66e --- /dev/null +++ b/event_reporter/reporter/app_revision.go @@ -0,0 +1,91 @@ +package reporter + +import ( + "context" + + "github.com/argoproj/argo-cd/v2/event_reporter/utils" + "github.com/argoproj/argo-cd/v2/pkg/apiclient/application" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + + log "github.com/sirupsen/logrus" +) + +// treats multi-sourced apps as single source and gets first revision details +func getApplicationLegacyRevisionDetails(a *v1alpha1.Application, revisionsWithMetadata *utils.AppSyncRevisionsMetadata) *v1alpha1.RevisionMetadata { + if len(revisionsWithMetadata.SyncRevisions) == 0 { + return nil + } + + sourceIdx := 0 + + if a.Spec.HasMultipleSources() { + _, sourceIdx = a.Spec.GetNonRefSource() + } + + if revisionWithMetadata := revisionsWithMetadata.SyncRevisions[sourceIdx]; revisionWithMetadata != nil { + return revisionWithMetadata.Metadata + } + + return nil +} + +func (s *applicationEventReporter) getRevisionsDetails(ctx context.Context, a *v1alpha1.Application, revisions []string) ([]*utils.RevisionWithMetadata, error) { + project := a.Spec.GetProject() + rms := make([]*utils.RevisionWithMetadata, 0) + + for idx, revision := range revisions { + // report just revision for helm sources + if a.Spec.SourceUnderIdxIsHelm(idx) { + rms = append(rms, &utils.RevisionWithMetadata{ + Revision: revision, + }) + continue + } + + sourceIndex := int32(idx) + + rm, err := s.applicationServiceClient.RevisionMetadata(ctx, &application.RevisionMetadataQuery{ + Name: &a.Name, + AppNamespace: &a.Namespace, + Revision: &revision, + Project: &project, + SourceIndex: &sourceIndex, + }) + if err != nil { + return nil, err + } + rms = append(rms, &utils.RevisionWithMetadata{ + Revision: revision, + Metadata: rm, + }) + } + + return rms, nil +} + +func (s *applicationEventReporter) getApplicationRevisionsMetadata(ctx context.Context, logCtx *log.Entry, a *v1alpha1.Application) (*utils.AppSyncRevisionsMetadata, error) { //nolint:golint,unparam + result := &utils.AppSyncRevisionsMetadata{} + + if a.Status.Sync.Revision != "" || a.Status.Sync.Revisions != nil || len(a.Status.History) > 0 { + // can be the latest revision of repository + operationSyncRevisionsMetadata, err := s.getRevisionsDetails(ctx, a, utils.GetOperationSyncRevisions(a)) + if err != nil { + logCtx.WithError(err).Warnf("failed to get application(%s) sync revisions metadata, resuming", a.GetName()) + } + + if err == nil && operationSyncRevisionsMetadata != nil { + result.SyncRevisions = operationSyncRevisionsMetadata + } + // latest revision of repository where changes to app resource were actually made; empty if no changeRevision(-s) present + operationChangeRevisionsMetadata, err := s.getRevisionsDetails(ctx, a, utils.GetOperationChangeRevisions(a)) + if err != nil { + logCtx.WithError(err).Warnf("failed to get application(%s) change revisions metadata, resuming", a.GetName()) + } + + if err == nil && operationChangeRevisionsMetadata != nil && len(operationChangeRevisionsMetadata) > 0 { + result.ChangeRevisions = operationChangeRevisionsMetadata + } + } + + return result, nil +} diff --git a/event_reporter/reporter/app_revision_test.go b/event_reporter/reporter/app_revision_test.go new file mode 100644 index 0000000000000..7ccaa52ba5471 --- /dev/null +++ b/event_reporter/reporter/app_revision_test.go @@ -0,0 +1,180 @@ +package reporter + +import ( + "context" + "testing" + + "github.com/argoproj/argo-cd/v2/event_reporter/application/mocks" + "github.com/argoproj/argo-cd/v2/event_reporter/metrics" + "github.com/argoproj/argo-cd/v2/event_reporter/utils" + "github.com/argoproj/argo-cd/v2/pkg/apiclient/application" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/server/cache" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" +) + +func TestGetRevisionsDetails(t *testing.T) { + t.Run("should return revisions for single source app", func(t *testing.T) { + expectedRevision := "expected-revision" + expectedResult := []*utils.RevisionWithMetadata{{ + Revision: expectedRevision, + Metadata: &v1alpha1.RevisionMetadata{ + Author: "Test Author", + Message: "first commit", + }, + }} + + app := v1alpha1.Application{ + Spec: v1alpha1.ApplicationSpec{ + Source: &v1alpha1.ApplicationSource{ + RepoURL: "https://my-site.com", + TargetRevision: "HEAD", + Path: ".", + }, + }, + } + + appServiceClient := mocks.NewApplicationClient(t) + project := app.Spec.GetProject() + sourceIdx1 := int32(0) + + appServiceClient.On("RevisionMetadata", mock.Anything, &application.RevisionMetadataQuery{ + Name: &app.Name, + AppNamespace: &app.Namespace, + Revision: &expectedResult[0].Revision, + Project: &project, + SourceIndex: &sourceIdx1, + }).Return(expectedResult[0].Metadata, nil) + + reporter := &applicationEventReporter{ + &cache.Cache{}, + &MockCodefreshClient{}, + newAppLister(), + appServiceClient, + &metrics.MetricsServer{}, + fakeArgoDb(), + "0.0.1", + false, + nil, + } + + result, _ := reporter.getRevisionsDetails(context.Background(), &app, []string{expectedRevision}) + + assert.Equal(t, expectedResult, result) + }) + + t.Run("should return revisions for multi sourced apps", func(t *testing.T) { + expectedRevision1 := "expected-revision-1" + expectedRevision2 := "expected-revision-2" + expectedResult := []*utils.RevisionWithMetadata{{ + Revision: expectedRevision1, + Metadata: &v1alpha1.RevisionMetadata{ + Author: "Repo1 Author", + Message: "first commit repo 1", + }, + }, { + Revision: expectedRevision2, + Metadata: &v1alpha1.RevisionMetadata{ + Author: "Repo2 Author", + Message: "first commit repo 2", + }, + }} + + app := v1alpha1.Application{ + Spec: v1alpha1.ApplicationSpec{ + Sources: []v1alpha1.ApplicationSource{{ + RepoURL: "https://my-site.com/repo-1", + TargetRevision: "branch1", + Path: ".", + }, { + RepoURL: "https://my-site.com/repo-2", + TargetRevision: "branch2", + Path: ".", + }}, + }, + } + + project := app.Spec.GetProject() + + appServiceClient := mocks.NewApplicationClient(t) + sourceIdx1 := int32(0) + sourceIdx2 := int32(1) + appServiceClient.On("RevisionMetadata", mock.Anything, &application.RevisionMetadataQuery{ + Name: &app.Name, + AppNamespace: &app.Namespace, + Revision: &expectedRevision1, + Project: &project, + SourceIndex: &sourceIdx1, + }).Return(expectedResult[0].Metadata, nil) + appServiceClient.On("RevisionMetadata", mock.Anything, &application.RevisionMetadataQuery{ + Name: &app.Name, + AppNamespace: &app.Namespace, + Revision: &expectedRevision2, + Project: &project, + SourceIndex: &sourceIdx2, + }).Return(expectedResult[1].Metadata, nil) + + reporter := &applicationEventReporter{ + &cache.Cache{}, + &MockCodefreshClient{}, + newAppLister(), + appServiceClient, + &metrics.MetricsServer{}, + fakeArgoDb(), + "0.0.1", + false, + nil, + } + + result, _ := reporter.getRevisionsDetails(context.Background(), &app, []string{expectedRevision1, expectedRevision2}) + + assert.Equal(t, expectedResult, result) + }) + + t.Run("should return only revision because of helm single source app", func(t *testing.T) { + expectedRevision := "expected-revision" + expectedResult := []*utils.RevisionWithMetadata{{ + Revision: expectedRevision, + }} + + app := v1alpha1.Application{ + Spec: v1alpha1.ApplicationSpec{ + Source: &v1alpha1.ApplicationSource{ + RepoURL: "https://my-site.com", + TargetRevision: "HEAD", + Path: ".", + }, + }, + } + + appServiceClient := mocks.NewApplicationClient(t) + project := app.Spec.GetProject() + sourceIdx1 := int32(0) + + appServiceClient.On("RevisionMetadata", mock.Anything, &application.RevisionMetadataQuery{ + Name: &app.Name, + AppNamespace: &app.Namespace, + Revision: &expectedResult[0].Revision, + Project: &project, + SourceIndex: &sourceIdx1, + }).Return(expectedResult[0].Metadata, nil) + + reporter := &applicationEventReporter{ + &cache.Cache{}, + &MockCodefreshClient{}, + newAppLister(), + appServiceClient, + &metrics.MetricsServer{}, + fakeArgoDb(), + "0.0.1", + false, + nil, + } + + result, _ := reporter.getRevisionsDetails(context.Background(), &app, []string{expectedRevision}) + + assert.Equal(t, expectedResult, result) + }) +} diff --git a/event_reporter/reporter/application_errors_parser.go b/event_reporter/reporter/application_errors_parser.go new file mode 100644 index 0000000000000..5c52d1a5cfde8 --- /dev/null +++ b/event_reporter/reporter/application_errors_parser.go @@ -0,0 +1,201 @@ +package reporter + +import ( + "fmt" + "strings" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + "github.com/argoproj/gitops-engine/pkg/health" + "github.com/argoproj/gitops-engine/pkg/sync/common" + + "github.com/argoproj/argo-cd/v2/pkg/apiclient/events" + appv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" +) + +func parseApplicationSyncResultErrors(os *appv1.OperationState) []*events.ObjectError { + var errors []*events.ObjectError + // mean that resource not found as sync result but application can contain error inside operation state itself, + // for example app created with invalid yaml + if os.Phase == common.OperationError || os.Phase == common.OperationFailed { + errors = append(errors, &events.ObjectError{ + Type: "sync", + Level: "error", + Message: os.Message, + LastSeen: os.StartedAt, + }) + } + return errors +} + +var ( + syncTaskUnsuccessfullErrorMessage = "one or more synchronization tasks completed unsuccessfully" + syncTaskNotValidErrorMessage = "one or more synchronization tasks are not valid" +) + +func parseApplicationSyncResultErrorsFromConditions(status appv1.ApplicationStatus) []*events.ObjectError { + var errs []*events.ObjectError + if status.Conditions == nil { + return errs + } + for _, cnd := range status.Conditions { + if (strings.Contains(cnd.Message, syncTaskUnsuccessfullErrorMessage) || strings.Contains(cnd.Message, syncTaskNotValidErrorMessage)) && status.OperationState != nil && status.OperationState.SyncResult != nil && status.OperationState.SyncResult.Resources != nil { + resourcesSyncErrors := parseAggregativeResourcesSyncErrors(status.OperationState.SyncResult.Resources) + + errs = append(errs, resourcesSyncErrors...) + continue + } + + if level := getConditionLevel(cnd); level != "" { + errs = append(errs, &events.ObjectError{ + Type: "sync", + Level: level, + Message: cnd.Message, + LastSeen: getConditionTime(cnd), + }) + } + } + return errs +} + +func getConditionLevel(cnd appv1.ApplicationCondition) string { + if cnd.IsWarning() { + return "warning" + } + if cnd.IsError() { + return "error" + } + return "" +} + +func getConditionTime(cnd appv1.ApplicationCondition) metav1.Time { + if cnd.LastTransitionTime != nil { + return *cnd.LastTransitionTime + } + return metav1.Now() +} + +func parseResourceSyncResultErrors(rs *appv1.ResourceStatus, os *appv1.OperationState) []*events.ObjectError { + errors := []*events.ObjectError{} + if os.SyncResult == nil { + return errors + } + + _, sr := os.SyncResult.Resources.Find( + rs.Group, + rs.Kind, + rs.Namespace, + rs.Name, + common.SyncPhaseSync, + ) + + if sr == nil || !(sr.HookPhase == common.OperationFailed || sr.HookPhase == common.OperationError || sr.Status == common.ResultCodeSyncFailed) { + return errors + } + + errors = append(errors, &events.ObjectError{ + Type: "sync", + Level: "error", + Message: sr.Message, + LastSeen: os.StartedAt, + }) + + return errors +} + +func parseAggregativeHealthErrorsOfApplication(a *appv1.Application, appTree *appv1.ApplicationTree) []*events.ObjectError { + var errors []*events.ObjectError + if a.Status.Resources == nil { + return errors + } + + for _, rs := range a.Status.Resources { + if rs.Health != nil { + if rs.Health.Status != health.HealthStatusHealthy { + errors = append(errors, parseAggregativeHealthErrors(&rs, appTree, true)...) + } + } + } + + return errors +} + +func parseAggregativeHealthErrors(rs *appv1.ResourceStatus, apptree *appv1.ApplicationTree, addReference bool) []*events.ObjectError { + errs := make([]*events.ObjectError, 0) + + if apptree == nil { + return errs + } + + n := apptree.FindNode(rs.Group, rs.Kind, rs.Namespace, rs.Name) + if n == nil { + return errs + } + + childNodes := n.GetAllChildNodes(apptree, "") + + for _, cn := range childNodes { + if newErr := getNodeHealthError(cn, rs, addReference); newErr != nil { + errs = append(errs, newErr) + } + } + + if len(errs) == 0 { + if newErr := getNodeHealthError(*n, rs, addReference); newErr != nil { + errs = append(errs, newErr) + } + } + + return errs +} + +func getNodeHealthError(node appv1.ResourceNode, managedResource *appv1.ResourceStatus, addReference bool) *events.ObjectError { + if node.Health == nil || node.Health.Status != health.HealthStatusDegraded { + return nil + } + + newErr := &events.ObjectError{ + Type: "health", + Level: "error", + Message: node.Health.Message, + LastSeen: *node.CreatedAt, + } + + if addReference { + newErr.SourceReference = &events.ErrorSourceReference{ + Group: managedResource.Group, + Version: managedResource.Version, + Kind: managedResource.Kind, + Namespace: managedResource.Namespace, + Name: managedResource.Name, + } + } + return newErr +} + +func parseAggregativeResourcesSyncErrors(resourceResults appv1.ResourceResults) []*events.ObjectError { + var errs []*events.ObjectError + + if resourceResults == nil { + return errs + } + + for _, rr := range resourceResults { + if rr.Message != "" { + objectError := events.ObjectError{ + Type: "sync", + Level: "error", + LastSeen: metav1.Now(), + Message: fmt.Sprintf("Resource %s(%s): \n %s", rr.Kind, rr.Name, rr.Message), + } + if rr.Status == common.ResultCodeSyncFailed { + errs = append(errs, &objectError) + } + if rr.HookPhase == common.OperationFailed || rr.HookPhase == common.OperationError { + errs = append(errs, &objectError) + } + } + } + + return errs +} diff --git a/event_reporter/reporter/application_event_reporter.go b/event_reporter/reporter/application_event_reporter.go new file mode 100644 index 0000000000000..a38602177ded9 --- /dev/null +++ b/event_reporter/reporter/application_event_reporter.go @@ -0,0 +1,610 @@ +package reporter + +import ( + "context" + "encoding/json" + "fmt" + "math" + "reflect" + "strings" + "time" + + "github.com/argoproj/argo-cd/v2/pkg/sources_server_client" + + "github.com/argoproj/argo-cd/v2/util/db" + + "github.com/argoproj/argo-cd/v2/event_reporter/utils" + + argoutils "github.com/argoproj/argo-cd/v2/util/argo" + + "github.com/argoproj/argo-cd/v2/reposerver/apiclient" + + argocommon "github.com/argoproj/argo-cd/v2/common" + "github.com/argoproj/argo-cd/v2/event_reporter/metrics" + applisters "github.com/argoproj/argo-cd/v2/pkg/client/listers/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/pkg/codefresh" + servercache "github.com/argoproj/argo-cd/v2/server/cache" + "github.com/argoproj/argo-cd/v2/util/env" + + "github.com/argoproj/gitops-engine/pkg/health" + "github.com/argoproj/gitops-engine/pkg/utils/kube" + "github.com/argoproj/gitops-engine/pkg/utils/text" + log "github.com/sirupsen/logrus" + "k8s.io/apimachinery/pkg/watch" + + appclient "github.com/argoproj/argo-cd/v2/event_reporter/application" + metricsUtils "github.com/argoproj/argo-cd/v2/event_reporter/metrics/utils" + "github.com/argoproj/argo-cd/v2/pkg/apiclient/application" + appv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" +) + +var resourceEventCacheExpiration = time.Minute * time.Duration(env.ParseNumFromEnv(argocommon.EnvResourceEventCacheDuration, 20, 0, math.MaxInt32)) + +type applicationEventReporter struct { + cache *servercache.Cache + codefreshClient codefresh.CodefreshClientInterface + appLister applisters.ApplicationLister + applicationServiceClient appclient.ApplicationClient + metricsServer *metrics.MetricsServer + db db.ArgoDB + runtimeVersion string + useSourcesServer bool + sourcesServerClient sources_server_client.SourceServerClientInteface +} + +type ApplicationEventReporter interface { + StreamApplicationEvents( + ctx context.Context, + a *appv1.Application, + eventProcessingStartedAt string, + ignoreResourceCache bool, + argoTrackingMetadata *ArgoTrackingMetadata, + ) error + ShouldSendApplicationEvent(ae *appv1.ApplicationWatchEvent) (shouldSend bool, syncStatusChanged bool) +} + +func NewApplicationEventReporter(cache *servercache.Cache, applicationServiceClient appclient.ApplicationClient, appLister applisters.ApplicationLister, codefreshConfig *codefresh.CodefreshConfig, metricsServer *metrics.MetricsServer, db db.ArgoDB, useSourcesServer bool, sourcesServerConfig *sources_server_client.SourcesServerConfig) ApplicationEventReporter { + return &applicationEventReporter{ + cache: cache, + applicationServiceClient: applicationServiceClient, + codefreshClient: codefresh.NewCodefreshClient(codefreshConfig), + appLister: appLister, + metricsServer: metricsServer, + db: db, + runtimeVersion: codefreshConfig.RuntimeVersion, + useSourcesServer: useSourcesServer, + sourcesServerClient: sources_server_client.NewSourceServerClient(sourcesServerConfig), + } +} + +func (s *applicationEventReporter) shouldSendResourceEvent(a *appv1.Application, rs appv1.ResourceStatus) bool { + logCtx := utils.LogWithResourceStatus(log.WithFields(log.Fields{ + "app": a.Name, + "gvk": fmt.Sprintf("%s/%s/%s", rs.Group, rs.Version, rs.Kind), + "resource": fmt.Sprintf("%s/%s", rs.Namespace, rs.Name), + }), rs) + + cachedRes, err := s.cache.GetLastResourceEvent(a, rs, utils.GetApplicationLatestRevision(a)) + if err != nil { + logCtx.Debug("resource not in cache") + return true + } + + if reflect.DeepEqual(&cachedRes, &rs) { + logCtx.Debug("resource status not changed") + + // status not changed + return false + } + + logCtx.Info("resource status changed") + return true +} + +func (r *applicationEventReporter) getDesiredManifests( + ctx context.Context, + logCtx *log.Entry, + a *appv1.Application, + revision *string, + sourcePositions *[]int64, + revisions *[]string, +) (*apiclient.ManifestResponse, bool) { + // get the desired state manifests of the application + project := a.Spec.GetProject() + query := application.ApplicationManifestQuery{ + Name: &a.Name, + AppNamespace: &a.Namespace, + Revision: revision, + Project: &project, + } + if sourcePositions != nil && query.Revisions != nil { + query.SourcePositions = *sourcePositions + query.Revisions = *revisions + } + + desiredManifests, err := r.applicationServiceClient.GetManifests(ctx, &query) + if err != nil { + // if it's manifest generation error we need to still report the actual state + // of the resources, but since we can't get the desired state, we will report + // each resource with empty desired state + logCtx.WithError(err).Warn("failed to get application desired state manifests, reporting actual state only") + desiredManifests = &apiclient.ManifestResponse{Manifests: []*apiclient.Manifest{}} + return desiredManifests, true // will ignore requiresPruning=true to not delete resources with actual state + } + return desiredManifests, false +} + +func (s *applicationEventReporter) StreamApplicationEvents( + ctx context.Context, + a *appv1.Application, + eventProcessingStartedAt string, + ignoreResourceCache bool, + argoTrackingMetadata *ArgoTrackingMetadata, +) error { + metricTimer := metricsUtils.NewMetricTimer() + + logCtx := log.WithField("app", a.Name) + logCtx.WithField("ignoreResourceCache", ignoreResourceCache).Info("streaming application events") + + project := a.Spec.GetProject() + appTree, err := s.applicationServiceClient.ResourceTree(ctx, &application.ResourcesQuery{ + ApplicationName: &a.Name, + Project: &project, + AppNamespace: &a.Namespace, + }) + if err != nil { + if strings.Contains(err.Error(), "context deadline exceeded") { + return fmt.Errorf("failed to get application tree: %w", err) + } + + // we still need process app even without tree, it is in case of app yaml originally contain error, + // we still want to show it the errors that related to it on codefresh ui + logCtx.WithError(err).Warn("failed to get application tree, resuming") + } + + logCtx.Info("getting desired manifests") + + desiredManifests, manifestGenErr := s.getDesiredManifests(ctx, logCtx, a, nil, nil, nil) + + applicationVersions := s.resolveApplicationVersions(ctx, a, logCtx) + + logCtx.Info("getting parent application name") + + parentAppIdentity := utils.GetParentAppIdentity(a, *argoTrackingMetadata.AppInstanceLabelKey, *argoTrackingMetadata.InstallationID, *argoTrackingMetadata.TrackingMethod) + + if utils.IsChildApp(parentAppIdentity) { + logCtx.Info("processing as child application") + parentApplicationEntity, err := s.applicationServiceClient.Get(ctx, &application.ApplicationQuery{ + Name: &parentAppIdentity.Name, + AppNamespace: &parentAppIdentity.Namespace, + }) + if err != nil { + return fmt.Errorf("failed to get parent application entity: %w", err) + } + + rs := utils.GetAppAsResource(a) + utils.SetHealthStatusIfMissing(rs) + + parentDesiredManifests, manifestGenErr := s.getDesiredManifests(ctx, logCtx, parentApplicationEntity, nil, nil, nil) + + parentAppSyncRevisionsMetadata, err := s.getApplicationRevisionsMetadata(ctx, logCtx, parentApplicationEntity) + if err != nil { + logCtx.WithError(err).Warn("failed to get parent application's revision metadata, resuming") + } + + validatedDestination := parentApplicationEntity.Spec.Destination.DeepCopy() + _ = argoutils.ValidateDestination(ctx, validatedDestination, s.db) // resolves server field if missing + + err = s.processResource(ctx, *rs, logCtx, eventProcessingStartedAt, parentDesiredManifests, manifestGenErr, a, applicationVersions, &ReportedEntityParentApp{ + app: parentApplicationEntity, + appTree: appTree, + revisionsMetadata: parentAppSyncRevisionsMetadata, + validatedDestination: validatedDestination, + }, argoTrackingMetadata) + if err != nil { + s.metricsServer.IncErroredEventsCounter(metrics.MetricChildAppEventType, metrics.MetricEventUnknownErrorType, a.Name) + return err + } + s.metricsServer.ObserveEventProcessingDurationHistogramDuration(a.Name, metrics.MetricChildAppEventType, metricTimer.Duration()) + } else { + // will get here only for root applications (not managed as a resource by another application) + logCtx.Info("processing as root application") + appEvent, err := s.getApplicationEventPayload(ctx, a, appTree, eventProcessingStartedAt, applicationVersions, argoTrackingMetadata, s.runtimeVersion) + if err != nil { + s.metricsServer.IncErroredEventsCounter(metrics.MetricParentAppEventType, metrics.MetricEventGetPayloadErrorType, a.Name) + return fmt.Errorf("failed to get application event: %w", err) + } + + if appEvent == nil { + // event did not have an OperationState - skip all events + return nil + } + + utils.LogWithAppStatus(a, logCtx, eventProcessingStartedAt).Info("sending root application event") + if err := s.codefreshClient.SendEvent(ctx, a.Name, appEvent); err != nil { + s.metricsServer.IncErroredEventsCounter(metrics.MetricParentAppEventType, metrics.MetricEventDeliveryErrorType, a.Name) + return fmt.Errorf("failed to send event for root application %s/%s: %w", a.Namespace, a.Name, err) + } + s.metricsServer.ObserveEventProcessingDurationHistogramDuration(a.Name, metrics.MetricParentAppEventType, metricTimer.Duration()) + } + + validatedDestination := a.Spec.Destination.DeepCopy() + _ = argoutils.ValidateDestination(ctx, validatedDestination, s.db) // resolves server field if missing + + revisionsMetadata, _ := s.getApplicationRevisionsMetadata(ctx, logCtx, a) + // for each resource in the application get desired and actual state, + // then stream the event + for _, rs := range a.Status.Resources { + if utils.IsApp(rs) { + continue + } + utils.SetHealthStatusIfMissing(&rs) + if !ignoreResourceCache && !s.shouldSendResourceEvent(a, rs) { + s.metricsServer.IncCachedIgnoredEventsCounter(metrics.MetricResourceEventType, a.Name) + continue + } + err := s.processResource(ctx, rs, logCtx, eventProcessingStartedAt, desiredManifests, manifestGenErr, nil, nil, &ReportedEntityParentApp{ + app: a, + appTree: appTree, + revisionsMetadata: revisionsMetadata, + validatedDestination: validatedDestination, + }, argoTrackingMetadata) + if err != nil { + s.metricsServer.IncErroredEventsCounter(metrics.MetricResourceEventType, metrics.MetricEventUnknownErrorType, a.Name) + return err + } + } + return nil +} + +// returns appVersion from first non-ref source for multisourced apps +func (s *applicationEventReporter) resolveApplicationVersions(ctx context.Context, a *appv1.Application, logCtx *log.Entry) *apiclient.ApplicationVersions { + if a.Spec.HasMultipleSources() { + syncResultRevisions := utils.GetOperationSyncResultRevisions(a) + if syncResultRevisions == nil { + return nil + } + + var sourcePositions []int64 + for i := 0; i < len(*syncResultRevisions); i++ { + sourcePositions = append(sourcePositions, int64(i+1)) + } + + syncManifests, _ := s.getDesiredManifests(ctx, logCtx, a, nil, &sourcePositions, syncResultRevisions) + + var applicationVersions *apiclient.ApplicationVersions + if s.useSourcesServer { + log.Infof("cfGetAppVersion. Getting version from sourcesserver") + if len(*syncResultRevisions) == 0 { + return nil + } + appVers := s.sourcesServerClient.GetAppVersion(a, &(*syncResultRevisions)[0]) + applicationVersions = utils.SourcesAppVersionsToRepo(appVers, logCtx) + } else { + applicationVersions = syncManifests.GetApplicationVersions() + } + + return applicationVersions + } + + syncResultRevision := utils.GetOperationSyncResultRevision(a) + + if syncResultRevision == nil { + return nil + } + + syncManifests, _ := s.getDesiredManifests(ctx, logCtx, a, syncResultRevision, nil, nil) + + var applicationVersions *apiclient.ApplicationVersions + if s.useSourcesServer { + log.Infof("cfGetAppVersion. Getting version from sourcesserver") + appVers := s.sourcesServerClient.GetAppVersion(a, syncResultRevision) + applicationVersions = utils.SourcesAppVersionsToRepo(appVers, logCtx) + } else { + applicationVersions = syncManifests.GetApplicationVersions() + } + return applicationVersions +} + +func (s *applicationEventReporter) getAppForResourceReporting( + rs appv1.ResourceStatus, + ctx context.Context, + logCtx *log.Entry, + a *appv1.Application, + syncRevisionsMetadata *utils.AppSyncRevisionsMetadata, +) (*appv1.Application, *utils.AppSyncRevisionsMetadata) { + if rs.Kind != "Rollout" { // for rollout it's crucial to report always correct operationSyncRevision + return a, syncRevisionsMetadata + } + + latestAppStatus, err := s.appLister.Applications(a.Namespace).Get(a.Name) + if err != nil { + return a, syncRevisionsMetadata + } + + revisionMetadataToReport, err := s.getApplicationRevisionsMetadata(ctx, logCtx, latestAppStatus) + if err != nil { + return a, syncRevisionsMetadata + } + + return latestAppStatus, revisionMetadataToReport +} + +func (s *applicationEventReporter) processResource( + ctx context.Context, + rs appv1.ResourceStatus, + logCtx *log.Entry, + appEventProcessingStartedAt string, + desiredManifests *apiclient.ManifestResponse, + manifestGenErr bool, + originalApplication *appv1.Application, // passed only if resource is app + applicationVersions *apiclient.ApplicationVersions, // passed only if resource is app + reportedEntityParentApp *ReportedEntityParentApp, + argoTrackingMetadata *ArgoTrackingMetadata, +) error { + if !isAllowedResource(rs) { + return nil + } + + metricsEventType := metrics.MetricResourceEventType + if utils.IsApp(rs) { + metricsEventType = metrics.MetricChildAppEventType + } + + logCtx = logCtx.WithFields(log.Fields{ + "gvk": fmt.Sprintf("%s/%s/%s", rs.Group, rs.Version, rs.Kind), + "resource": fmt.Sprintf("%s/%s", rs.Namespace, rs.Name), + }) + + // get resource desired state + desiredState, appSourceIdx := getResourceDesiredState(&rs, desiredManifests, logCtx) + + actualState, err := s.getResourceActualState(ctx, logCtx, metricsEventType, rs, reportedEntityParentApp.app, originalApplication) + if err != nil { + return err + } + if actualState == nil { + return nil + } + + if rs.Kind == "ConfigMap" && !isAllowedConfigMap(*actualState.Manifest) { + return nil + } + + parentApplicationToReport, revisionMetadataToReport := s.getAppForResourceReporting(rs, ctx, logCtx, reportedEntityParentApp.app, reportedEntityParentApp.revisionsMetadata) + + var originalAppRevisionMetadata *utils.AppSyncRevisionsMetadata = nil + + if originalApplication != nil { + originalAppRevisionMetadata, _ = s.getApplicationRevisionsMetadata(ctx, logCtx, originalApplication) + } + + ev, err := getResourceEventPayload( + appEventProcessingStartedAt, + &ReportedResource{ + rs: &rs, + actualState: actualState, + desiredState: desiredState, + manifestGenErr: manifestGenErr, + appSourceIdx: appSourceIdx, + rsAsAppInfo: &ReportedResourceAsApp{ + app: originalApplication, + revisionsMetadata: originalAppRevisionMetadata, + applicationVersions: applicationVersions, + }, + }, + &ReportedEntityParentApp{ + app: parentApplicationToReport, + appTree: reportedEntityParentApp.appTree, + revisionsMetadata: revisionMetadataToReport, + validatedDestination: reportedEntityParentApp.validatedDestination, + desiredManifests: reportedEntityParentApp.desiredManifests, + }, + argoTrackingMetadata, + s.runtimeVersion, + ) + if err != nil { + s.metricsServer.IncErroredEventsCounter(metricsEventType, metrics.MetricEventGetPayloadErrorType, reportedEntityParentApp.app.Name) + logCtx.WithError(err).Warn("failed to get event payload, resuming") + return nil + } + + appRes := appv1.Application{} + appName := "" + if utils.IsApp(rs) && actualState.Manifest != nil && json.Unmarshal([]byte(*actualState.Manifest), &appRes) == nil { + utils.LogWithAppStatus(&appRes, logCtx, appEventProcessingStartedAt).Info("streaming resource event") + appName = appRes.Name + } else { + utils.LogWithResourceStatus(logCtx, rs).Info("streaming resource event") + appName = reportedEntityParentApp.app.Name + } + + if err := s.codefreshClient.SendEvent(ctx, appName, ev); err != nil { + if strings.Contains(err.Error(), "context deadline exceeded") { + return fmt.Errorf("failed to send resource event: %w", err) + } + + s.metricsServer.IncErroredEventsCounter(metricsEventType, metrics.MetricEventDeliveryErrorType, appName) + logCtx.WithError(err).Warn("failed to send resource event, resuming") + return nil + } + + if err := s.cache.SetLastResourceEvent(parentApplicationToReport, rs, resourceEventCacheExpiration, utils.GetApplicationLatestRevision(parentApplicationToReport)); err != nil { + logCtx.WithError(err).Warn("failed to cache resource event") + } + + return nil +} + +func (s *applicationEventReporter) getResourceActualState(ctx context.Context, logCtx *log.Entry, metricsEventType metrics.MetricEventType, rs appv1.ResourceStatus, parentApplication *appv1.Application, childApplication *appv1.Application) (*application.ApplicationResourceResponse, error) { + if utils.IsApp(rs) { + if childApplication.IsEmptyTypeMeta() { + // make sure there is type meta on object + childApplication.SetDefaultTypeMeta() + } + + manifestBytes, err := json.Marshal(childApplication) + + if err == nil && len(manifestBytes) > 0 { + manifest := string(manifestBytes) + return &application.ApplicationResourceResponse{Manifest: &manifest}, nil + } + } + + // get resource actual state + project := parentApplication.Spec.GetProject() + + actualState, err := s.applicationServiceClient.GetResource(ctx, &application.ApplicationResourceRequest{ + Name: &parentApplication.Name, + AppNamespace: &parentApplication.Namespace, + Namespace: &rs.Namespace, + ResourceName: &rs.Name, + Version: &rs.Version, + Group: &rs.Group, + Kind: &rs.Kind, + Project: &project, + }) + if err != nil { + if !strings.Contains(err.Error(), "not found") { + // only return error if there is no point in trying to send the + // next resource. For example if the shared context has exceeded + // its deadline + if strings.Contains(err.Error(), "context deadline exceeded") { + return nil, fmt.Errorf("failed to get actual state: %w", err) + } + + s.metricsServer.IncErroredEventsCounter(metricsEventType, metrics.MetricEventUnknownErrorType, parentApplication.Name) + logCtx.WithError(err).Warn("failed to get actual state, resuming") + return nil, nil + } + + manifest := "" + // empty actual state + actualState = &application.ApplicationResourceResponse{Manifest: &manifest} + } + + return actualState, nil +} + +func (s *applicationEventReporter) ShouldSendApplicationEvent(ae *appv1.ApplicationWatchEvent) (shouldSend bool, syncStatusChanged bool) { + logCtx := log.WithField("app", ae.Application.Name) + + if ae.Type == watch.Deleted { + logCtx.Info("application deleted") + return true, false + } + + cachedApp, err := s.cache.GetLastApplicationEvent(&ae.Application) + if err != nil || cachedApp == nil { + return true, false + } + + cachedApp.Status.ReconciledAt = ae.Application.Status.ReconciledAt // ignore those in the diff + cachedApp.Spec.Project = ae.Application.Spec.Project // not using GetProject() so that the comparison will be with the real field values + for i := range cachedApp.Status.Conditions { + cachedApp.Status.Conditions[i].LastTransitionTime = nil + } + for i := range ae.Application.Status.Conditions { + ae.Application.Status.Conditions[i].LastTransitionTime = nil + } + + // check if application changed to healthy status + if ae.Application.Status.Health.Status == health.HealthStatusHealthy && cachedApp.Status.Health.Status != health.HealthStatusHealthy { + return true, true + } + + if !reflect.DeepEqual(ae.Application.Spec, cachedApp.Spec) { + logCtx.Info("application spec changed") + return true, false + } + + if !reflect.DeepEqual(ae.Application.Status, cachedApp.Status) { + logCtx.Info("application status changed") + return true, false + } + + if !reflect.DeepEqual(ae.Application.Operation, cachedApp.Operation) { + logCtx.Info("application operation changed") + return true, false + } + + metadataChanged := applicationMetadataChanged(ae, cachedApp) + + if metadataChanged { + logCtx.Info("application metadata changed") + return true, false + } + + return false, false +} + +func applicationMetadataChanged(ae *appv1.ApplicationWatchEvent, cachedApp *appv1.Application) (changed bool) { + if ae.Type != watch.Modified { + return false + } + + cachedAppMeta := cachedApp.ObjectMeta.DeepCopy() + newEventAppMeta := ae.Application.ObjectMeta.DeepCopy() + + if newEventAppMeta.Annotations != nil { + delete(newEventAppMeta.Annotations, "kubectl.kubernetes.io/last-applied-configuration") + delete(cachedAppMeta.Annotations, "kubectl.kubernetes.io/last-applied-configuration") + } + + cachedAppMeta.ResourceVersion = newEventAppMeta.ResourceVersion // ignore those in the diff + cachedAppMeta.Generation = newEventAppMeta.Generation // ignore those in the diff + cachedAppMeta.GenerateName = newEventAppMeta.GenerateName // ignore those in the diff + newEventAppMeta.ManagedFields = nil // ignore those in the diff + cachedAppMeta.ManagedFields = nil // ignore those in the diff + + return !reflect.DeepEqual(newEventAppMeta, cachedAppMeta) +} + +func getResourceDesiredState(rs *appv1.ResourceStatus, ds *apiclient.ManifestResponse, logger *log.Entry) (manifest *apiclient.Manifest, sourceIdx int32) { + if ds == nil { + return &apiclient.Manifest{}, 0 + } + for idx, m := range ds.Manifests { + u, err := appv1.UnmarshalToUnstructured(m.CompiledManifest) + if err != nil { + logger.WithError(err).Warnf("failed to unmarshal compiled manifest") + continue + } + + if u == nil { + continue + } + + ns := text.FirstNonEmpty(u.GetNamespace(), rs.Namespace) + + if u.GroupVersionKind().String() == rs.GroupVersionKind().String() && + u.GetName() == rs.Name && + ns == rs.Namespace { + if rs.Kind == kube.SecretKind && rs.Version == "v1" { + m.RawManifest = m.CompiledManifest + } + + return m, getResourceSourceIdxFromManifestResponse(idx, ds) + } + } + + // no desired state for resource + // it's probably deleted from git + return &apiclient.Manifest{}, 0 +} + +func getResourceSourceIdxFromManifestResponse(rsIdx int, ds *apiclient.ManifestResponse) int32 { + if ds.SourcesManifestsStartingIdx == nil { + return -1 + } + + sourceIdx := int32(-1) + + for currentSourceIdx, sourceStartingIdx := range ds.SourcesManifestsStartingIdx { + if int32(rsIdx) >= sourceStartingIdx { + sourceIdx = int32(currentSourceIdx) + } + } + + return sourceIdx +} diff --git a/event_reporter/reporter/application_event_reporter_test.go b/event_reporter/reporter/application_event_reporter_test.go new file mode 100644 index 0000000000000..b3fc5a6cdb868 --- /dev/null +++ b/event_reporter/reporter/application_event_reporter_test.go @@ -0,0 +1,494 @@ +package reporter + +import ( + "context" + "encoding/json" + "fmt" + "net/http" + "testing" + "time" + + "github.com/argoproj/argo-cd/v2/util/db" + "github.com/argoproj/argo-cd/v2/util/settings" + + "k8s.io/client-go/kubernetes/fake" + + "github.com/aws/smithy-go/ptr" + "github.com/sirupsen/logrus" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" + "k8s.io/apimachinery/pkg/watch" + + "google.golang.org/grpc" + "k8s.io/apimachinery/pkg/runtime" + + appclient "github.com/argoproj/argo-cd/v2/event_reporter/application" + appMocks "github.com/argoproj/argo-cd/v2/event_reporter/application/mocks" + "github.com/argoproj/argo-cd/v2/pkg/apiclient" + apiclientapppkg "github.com/argoproj/argo-cd/v2/pkg/apiclient/application" + appv1reg "github.com/argoproj/argo-cd/v2/pkg/apis/application" + repoapiclient "github.com/argoproj/argo-cd/v2/reposerver/apiclient" + "github.com/argoproj/argo-cd/v2/util/io" + + "github.com/argoproj/argo-cd/v2/event_reporter/metrics" + + appsv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + fakeapps "github.com/argoproj/argo-cd/v2/pkg/client/clientset/versioned/fake" + appinformer "github.com/argoproj/argo-cd/v2/pkg/client/informers/externalversions" + applisters "github.com/argoproj/argo-cd/v2/pkg/client/listers/application/v1alpha1" + + servercache "github.com/argoproj/argo-cd/v2/server/cache" + cacheutil "github.com/argoproj/argo-cd/v2/util/cache" + appstatecache "github.com/argoproj/argo-cd/v2/util/cache/appstate" + + "github.com/stretchr/testify/assert" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + "github.com/argoproj/argo-cd/v2/pkg/apiclient/application" + "github.com/argoproj/argo-cd/v2/pkg/apiclient/events" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/pkg/codefresh" +) + +const ( + testNamespace = "default" +) + +func newAppLister(objects ...runtime.Object) applisters.ApplicationLister { + fakeAppsClientset := fakeapps.NewSimpleClientset(objects...) + factory := appinformer.NewSharedInformerFactoryWithOptions(fakeAppsClientset, 0, appinformer.WithNamespace(""), appinformer.WithTweakListOptions(func(options *metav1.ListOptions) {})) + appsInformer := factory.Argoproj().V1alpha1().Applications() + for _, obj := range objects { + switch obj.(type) { + case *appsv1.Application: + _ = appsInformer.Informer().GetStore().Add(obj) + } + } + appLister := appsInformer.Lister() + return appLister +} + +type MockcodefreshClient interface { + Send(ctx context.Context, appName string, event *events.Event) error +} + +type MockCodefreshConfig struct { + BaseURL string + AuthToken string +} + +type MockCodefreshClient struct { + cfConfig *MockCodefreshConfig + httpClient *http.Client +} + +func (cc *MockCodefreshClient) SendEvent(ctx context.Context, appName string, event *events.Event) error { + return nil +} + +func (cc *MockCodefreshClient) SendGraphQL(query codefresh.GraphQLQuery) (*json.RawMessage, error) { + return nil, nil +} + +func fakeAppServiceClient() apiclientapppkg.ApplicationServiceClient { + closer, applicationServiceClient, _ := apiclient.NewClientOrDie(&apiclient.ClientOptions{ + ServerAddr: "site.com", + }).NewApplicationClient() + defer io.Close(closer) + + return applicationServiceClient +} + +func fakeArgoDb() db.ArgoDB { + clientset := fake.NewSimpleClientset() + + return db.NewDB("", settings.NewSettingsManager(context.Background(), clientset, testNamespace), clientset) +} + +func fakeReporter(customAppServiceClient appclient.ApplicationClient) *applicationEventReporter { + guestbookApp := &appsv1.Application{ + TypeMeta: metav1.TypeMeta{ + Kind: "Application", + APIVersion: "argoproj.io/v1alpha1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "guestbook", + Namespace: testNamespace, + }, + Spec: appsv1.ApplicationSpec{ + Project: "default", + Source: &appsv1.ApplicationSource{ + RepoURL: "https://test", + TargetRevision: "HEAD", + Helm: &appsv1.ApplicationSourceHelm{ + ValueFiles: []string{"values.yaml"}, + }, + }, + }, + Status: appsv1.ApplicationStatus{ + History: appsv1.RevisionHistories{ + { + Revision: "abcdef123567", + Source: appsv1.ApplicationSource{ + RepoURL: "https://test", + TargetRevision: "HEAD", + Helm: &appsv1.ApplicationSourceHelm{ + ValueFiles: []string{"values-old.yaml"}, + }, + }, + }, + }, + }, + } + + appLister := newAppLister(guestbookApp) + + cache := servercache.NewCache( + appstatecache.NewCache( + cacheutil.NewCache(cacheutil.NewInMemoryCache(1*time.Hour)), + 1*time.Minute, + ), + 1*time.Minute, + 1*time.Minute, + 1*time.Minute, + ) + + cfClient := &MockCodefreshClient{ + cfConfig: &MockCodefreshConfig{ + BaseURL: "", + AuthToken: "", + }, + httpClient: &http.Client{ + Timeout: 30 * time.Second, + }, + } + + metricsServ := metrics.NewMetricsServer("", 8099) + + return &applicationEventReporter{ + cache, + cfClient, + appLister, + customAppServiceClient, + metricsServ, + fakeArgoDb(), + "0.0.1", + false, + nil, + } +} + +func TestShouldSendEvent(t *testing.T) { + eventReporter := fakeReporter(fakeAppServiceClient()) + t.Run("should send because cache is missing", func(t *testing.T) { + app := &v1alpha1.Application{} + rs := v1alpha1.ResourceStatus{} + + res := eventReporter.shouldSendResourceEvent(app, rs) + assert.True(t, res) + }) + + t.Run("should not send - same entities", func(t *testing.T) { + app := &v1alpha1.Application{} + rs := v1alpha1.ResourceStatus{} + + _ = eventReporter.cache.SetLastResourceEvent(app, rs, time.Minute, "") + + res := eventReporter.shouldSendResourceEvent(app, rs) + assert.False(t, res) + }) + + t.Run("should send - different entities", func(t *testing.T) { + app := &v1alpha1.Application{} + rs := v1alpha1.ResourceStatus{} + + _ = eventReporter.cache.SetLastResourceEvent(app, rs, time.Minute, "") + + rs.Status = v1alpha1.SyncStatusCodeOutOfSync + + res := eventReporter.shouldSendResourceEvent(app, rs) + assert.True(t, res) + }) +} + +type MockEventing_StartEventSourceServer struct { + grpc.ServerStream +} + +var result func(*events.Event) error + +func (m *MockEventing_StartEventSourceServer) Send(event *events.Event) error { + return result(event) +} + +func TestStreamApplicationEvent(t *testing.T) { + eventReporter := fakeReporter(fakeAppServiceClient()) + t.Run("root application", func(t *testing.T) { + app := &v1alpha1.Application{ + TypeMeta: metav1.TypeMeta{ + APIVersion: "argoproj.io/v1alpha1", + Kind: "Application", + }, + } + + result = func(event *events.Event) error { + var payload events.EventPayload + _ = json.Unmarshal(event.Payload, &payload) + + var actualApp v1alpha1.Application + _ = json.Unmarshal([]byte(payload.Source.ActualManifest), &actualApp) + assert.Equal(t, *app, actualApp) + return nil + } + _ = eventReporter.StreamApplicationEvents(context.Background(), app, "", false, getMockedArgoTrackingMetadata()) + }) +} + +func TestShouldSendApplicationEvent(t *testing.T) { + eventReporter := fakeReporter(fakeAppServiceClient()) + + t.Run("should send because cache is missing", func(t *testing.T) { + app := v1alpha1.Application{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "sdsds": "sdsd", + }, + }, + } + + shouldSend, _ := eventReporter.ShouldSendApplicationEvent(&v1alpha1.ApplicationWatchEvent{ + Type: watch.Modified, + Application: app, + }) + assert.True(t, shouldSend) + }) + + t.Run("should send because labels changed", func(t *testing.T) { + appCache := v1alpha1.Application{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "data": "old value", + }, + }, + } + + err := eventReporter.cache.SetLastApplicationEvent(&appCache, time.Second*5) + require.NoError(t, err) + + app := v1alpha1.Application{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "data": "new value", + }, + }, + } + + shouldSend, _ := eventReporter.ShouldSendApplicationEvent(&v1alpha1.ApplicationWatchEvent{ + Type: watch.Modified, + Application: app, + }) + assert.True(t, shouldSend) + }) + + t.Run("should send because annotations changed", func(t *testing.T) { + appCache := v1alpha1.Application{ + ObjectMeta: metav1.ObjectMeta{ + Annotations: map[string]string{ + "data": "old value", + }, + }, + } + + err := eventReporter.cache.SetLastApplicationEvent(&appCache, time.Second*5) + require.NoError(t, err) + + app := v1alpha1.Application{ + ObjectMeta: metav1.ObjectMeta{ + Annotations: map[string]string{ + "data": "new value", + }, + }, + } + + shouldSend, _ := eventReporter.ShouldSendApplicationEvent(&v1alpha1.ApplicationWatchEvent{ + Type: watch.Modified, + Application: app, + }) + assert.True(t, shouldSend) + }) + + t.Run("should ignore some changed metadata fields", func(t *testing.T) { + appCache := v1alpha1.Application{ + ObjectMeta: metav1.ObjectMeta{ + ResourceVersion: "1", + Generation: 1, + GenerateName: "first", + ManagedFields: []metav1.ManagedFieldsEntry{}, + Annotations: map[string]string{ + "kubectl.kubernetes.io/last-applied-configuration": "first", + }, + }, + } + + err := eventReporter.cache.SetLastApplicationEvent(&appCache, time.Second*5) + require.NoError(t, err) + + app := v1alpha1.Application{ + ObjectMeta: metav1.ObjectMeta{ + ResourceVersion: "2", + Generation: 2, + GenerateName: "changed", + ManagedFields: []metav1.ManagedFieldsEntry{{Manager: "changed"}}, + Annotations: map[string]string{ + "kubectl.kubernetes.io/last-applied-configuration": "changed", + }, + }, + } + + shouldSend, _ := eventReporter.ShouldSendApplicationEvent(&v1alpha1.ApplicationWatchEvent{ + Type: watch.Modified, + Application: app, + }) + assert.False(t, shouldSend) + }) +} + +func TestGetResourceActualState(t *testing.T) { + ctx := context.Background() + // Create a new logrus entry (assuming you have a configured logger) + logEntry := logrus.NewEntry(logrus.StandardLogger()) + + t.Run("should use existing app event for application", func(t *testing.T) { + eventReporter := fakeReporter(fakeAppServiceClient()) + + appEvent := v1alpha1.Application{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-app", + Namespace: "test-app-ns", + }, + } + + parentApp := v1alpha1.Application{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-parent-app", + Namespace: "test-app-ns", + }, + Spec: appsv1.ApplicationSpec{ + Project: appsv1.DefaultAppProjectName, + }, + } + rs := v1alpha1.ResourceStatus{ + Group: v1alpha1.ApplicationSchemaGroupVersionKind.Group, + Version: v1alpha1.ApplicationSchemaGroupVersionKind.Version, + Kind: v1alpha1.ApplicationSchemaGroupVersionKind.Kind, + } + + res, err := eventReporter.getResourceActualState(ctx, logEntry, metrics.MetricAppEventType, rs, &parentApp, &appEvent) + require.NoError(t, err) + + var manifestApp v1alpha1.Application + if err := json.Unmarshal([]byte(*res.Manifest), &manifestApp); err != nil { + t.Fatalf("failed to unmarshal manifest: %v", err) + } + + assert.Equal(t, manifestApp.ObjectMeta.Name, appEvent.ObjectMeta.Name) + // should set type meta + assert.Equal(t, "Application", appEvent.TypeMeta.Kind) + assert.Equal(t, "argoproj.io/v1alpha1", appEvent.TypeMeta.APIVersion) + }) + + t.Run("should get resource actual state for non-app resources", func(t *testing.T) { + expectedAppSetName := "test-app-set" + appSetCurrentActualState := v1alpha1.ApplicationSet{ + TypeMeta: metav1.TypeMeta{ + Kind: appv1reg.ApplicationSetKind, + APIVersion: v1alpha1.SchemeGroupVersion.String(), + }, + ObjectMeta: metav1.ObjectMeta{ + Name: expectedAppSetName, + Namespace: "test-app-ns", + }, + } + manifestBytes, err := json.Marshal(appSetCurrentActualState) + + if len(manifestBytes) == 0 && err != nil { + t.Fatalf("failed to Marshal manifest: %v", err) + } + + manifest := string(manifestBytes) + + appServiceClient := &appMocks.ApplicationClient{} + appServiceClient.On("GetResource", mock.Anything, mock.Anything).Return(&application.ApplicationResourceResponse{Manifest: &manifest}, nil) + + eventReporter := fakeReporter(appServiceClient) + + parentApp := v1alpha1.Application{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-parent-app", + Namespace: "test-app-ns", + }, + Spec: appsv1.ApplicationSpec{ + Project: appsv1.DefaultAppProjectName, + }, + } + rs := v1alpha1.ResourceStatus{ + Group: v1alpha1.ApplicationSchemaGroupVersionKind.Group, + Version: v1alpha1.ApplicationSchemaGroupVersionKind.Version, + Kind: "ApplicationSet", + } + + res, err := eventReporter.getResourceActualState(ctx, logEntry, metrics.MetricAppEventType, rs, &parentApp, nil) + require.NoError(t, err) + + var manifestApp v1alpha1.Application + if err := json.Unmarshal([]byte(*res.Manifest), &manifestApp); err != nil { + t.Fatalf("failed to unmarshal manifest: %v", err) + } + + assert.Equal(t, expectedAppSetName, manifestApp.ObjectMeta.Name) + assert.Equal(t, appv1reg.ApplicationSetKind, manifestApp.TypeMeta.Kind) + }) + + t.Run("should return empty manifest for not found resources", func(t *testing.T) { + appServiceClient := &appMocks.ApplicationClient{} + appServiceClient.On("GetResource", mock.Anything, mock.Anything).Return(nil, fmt.Errorf("not found resource")) + + eventReporter := fakeReporter(appServiceClient) + + parentApp := v1alpha1.Application{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-parent-app", + Namespace: "test-app-ns", + }, + Spec: appsv1.ApplicationSpec{ + Project: appsv1.DefaultAppProjectName, + }, + } + rs := v1alpha1.ResourceStatus{ + Group: v1alpha1.ApplicationSchemaGroupVersionKind.Group, + Version: v1alpha1.ApplicationSchemaGroupVersionKind.Version, + Kind: "ApplicationSet", + } + + res, err := eventReporter.getResourceActualState(ctx, logEntry, metrics.MetricAppEventType, rs, &parentApp, nil) + require.NoError(t, err) + assert.Equal(t, "", ptr.ToString(res.Manifest)) + }) +} + +func TestGetResourceSourceIdxFromManifestResponse(t *testing.T) { + t.Run("should return correct sourceIdx", func(t *testing.T) { + sourcesManifestsStartingIdx := []int32{0, 5, 15} + desiredManifests := &repoapiclient.ManifestResponse{ + SourcesManifestsStartingIdx: sourcesManifestsStartingIdx, + } + + assert.Equal(t, int32(0), getResourceSourceIdxFromManifestResponse(0, desiredManifests)) + assert.Equal(t, int32(0), getResourceSourceIdxFromManifestResponse(1, desiredManifests)) + assert.Equal(t, int32(1), getResourceSourceIdxFromManifestResponse(5, desiredManifests)) + assert.Equal(t, int32(1), getResourceSourceIdxFromManifestResponse(6, desiredManifests)) + assert.Equal(t, int32(2), getResourceSourceIdxFromManifestResponse(15, desiredManifests)) + assert.Equal(t, int32(2), getResourceSourceIdxFromManifestResponse(16, desiredManifests)) + assert.Equal(t, int32(-1), getResourceSourceIdxFromManifestResponse(2, &repoapiclient.ManifestResponse{})) + }) +} diff --git a/event_reporter/reporter/applications_errors_parser_test.go b/event_reporter/reporter/applications_errors_parser_test.go new file mode 100644 index 0000000000000..60a820f0fba05 --- /dev/null +++ b/event_reporter/reporter/applications_errors_parser_test.go @@ -0,0 +1,416 @@ +package reporter + +import ( + "fmt" + "testing" + "time" + + "github.com/argoproj/gitops-engine/pkg/health" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + "github.com/argoproj/gitops-engine/pkg/sync/common" + "github.com/stretchr/testify/assert" + + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" +) + +func TestParseResourceSyncResultErrors(t *testing.T) { + t.Run("Resource of app contain error that contain comma", func(t *testing.T) { + errors := parseResourceSyncResultErrors(&v1alpha1.ResourceStatus{ + Group: "group", + Kind: "kind", + Namespace: "namespace", + Name: "name", + }, &v1alpha1.OperationState{ + SyncResult: &v1alpha1.SyncOperationResult{ + Resources: v1alpha1.ResourceResults{ + { + Group: "group", + Kind: "kind", + Namespace: "namespace", + Name: "name", + SyncPhase: common.SyncPhaseSync, + Message: "error message, with comma", + HookPhase: common.OperationFailed, + }, + { + Group: "group", + Kind: "kind", + Namespace: "namespace", + Name: "name-2", + SyncPhase: common.SyncPhaseSync, + }, + }, + Revision: "123", + Source: v1alpha1.ApplicationSource{}, + }, + }) + + assert.Len(t, errors, 1) + assert.Equal(t, "error message, with comma", errors[0].Message) + assert.Equal(t, "sync", errors[0].Type) + assert.Equal(t, "error", errors[0].Level) + }) + t.Run("Resource of app contain error", func(t *testing.T) { + errors := parseResourceSyncResultErrors(&v1alpha1.ResourceStatus{ + Group: "group", + Kind: "kind", + Namespace: "namespace", + Name: "name", + }, &v1alpha1.OperationState{ + SyncResult: &v1alpha1.SyncOperationResult{ + Resources: v1alpha1.ResourceResults{ + { + Group: "group", + Kind: "kind", + Namespace: "namespace", + Name: "name", + SyncPhase: common.SyncPhaseSync, + Message: "error message", + HookPhase: common.OperationFailed, + }, + { + Group: "group", + Kind: "kind", + Namespace: "namespace", + Name: "name-2", + SyncPhase: common.SyncPhaseSync, + }, + }, + Revision: "123", + Source: v1alpha1.ApplicationSource{}, + }, + }) + + assert.Len(t, errors, 1) + assert.Equal(t, "error message", errors[0].Message) + assert.Equal(t, "sync", errors[0].Type) + assert.Equal(t, "error", errors[0].Level) + }) + t.Run("Resource of app not contain error", func(t *testing.T) { + errors := parseResourceSyncResultErrors(&v1alpha1.ResourceStatus{ + Group: "group", + Kind: "kind", + Namespace: "namespace", + Name: "name", + }, &v1alpha1.OperationState{ + SyncResult: &v1alpha1.SyncOperationResult{ + Resources: v1alpha1.ResourceResults{ + { + Group: "group", + Kind: "kind", + Namespace: "namespace", + Name: "name", + SyncPhase: common.SyncPhaseSync, + Message: "error message", + HookPhase: common.OperationSucceeded, + }, + { + Group: "group", + Kind: "kind", + Namespace: "namespace", + Name: "name-2", + SyncPhase: common.SyncPhaseSync, + }, + }, + Revision: "123", + Source: v1alpha1.ApplicationSource{}, + }, + }) + + assert.Empty(t, errors) + }) + t.Run("App of app contain error", func(t *testing.T) { + errors := parseApplicationSyncResultErrors(&v1alpha1.OperationState{ + Phase: common.OperationError, + Message: "error message", + SyncResult: &v1alpha1.SyncOperationResult{ + Revision: "123", + Source: v1alpha1.ApplicationSource{}, + }, + }) + + assert.Len(t, errors, 1) + assert.Equal(t, "error message", errors[0].Message) + assert.Equal(t, "sync", errors[0].Type) + assert.Equal(t, "error", errors[0].Level) + }) +} + +func TestGetConditionLevel(t *testing.T) { + errorsTypes := []v1alpha1.ApplicationCondition{ + {Type: v1alpha1.ApplicationConditionDeletionError}, + {Type: v1alpha1.ApplicationConditionInvalidSpecError}, + {Type: v1alpha1.ApplicationConditionComparisonError}, + {Type: v1alpha1.ApplicationConditionSyncError}, + {Type: v1alpha1.ApplicationConditionUnknownError}, + } + for _, errorAppCondition := range errorsTypes { + t.Run("parses as error "+errorAppCondition.Type, func(t *testing.T) { + level := getConditionLevel(errorAppCondition) + assert.Equal(t, "error", level) + }) + } + + warningTypes := []v1alpha1.ApplicationCondition{ + {Type: v1alpha1.ApplicationConditionSharedResourceWarning}, + {Type: v1alpha1.ApplicationConditionRepeatedResourceWarning}, + {Type: v1alpha1.ApplicationConditionExcludedResourceWarning}, + {Type: v1alpha1.ApplicationConditionOrphanedResourceWarning}, + } + for _, warningAppCondition := range warningTypes { + t.Run("parses as warning "+warningAppCondition.Type, func(t *testing.T) { + level := getConditionLevel(warningAppCondition) + assert.Equal(t, "warning", level) + }) + } +} + +func TestParseApplicationSyncResultErrorsFromConditions(t *testing.T) { + t.Run("conditions exists", func(t *testing.T) { + errors := parseApplicationSyncResultErrorsFromConditions(v1alpha1.ApplicationStatus{ + Conditions: []v1alpha1.ApplicationCondition{ + { + Type: v1alpha1.ApplicationConditionSyncError, + Message: "error message", + }, + }, + }) + + assert.Len(t, errors, 1) + assert.Equal(t, "error message", errors[0].Message) + assert.Equal(t, "sync", errors[0].Type) + assert.Equal(t, "error", errors[0].Level) + }) + + t.Run("warning exists", func(t *testing.T) { + errors := parseApplicationSyncResultErrorsFromConditions(v1alpha1.ApplicationStatus{ + Conditions: []v1alpha1.ApplicationCondition{ + { + Type: v1alpha1.ApplicationConditionOrphanedResourceWarning, + Message: "Application has 8 orphaned resources", + }, + }, + }) + + assert.Len(t, errors, 1) + assert.Equal(t, "Application has 8 orphaned resources", errors[0].Message) + assert.Equal(t, "sync", errors[0].Type) + assert.Equal(t, "warning", errors[0].Level) + }) + + t.Run("conditions erorr replaced with sync result errors", func(t *testing.T) { + errors := parseApplicationSyncResultErrorsFromConditions(v1alpha1.ApplicationStatus{ + Conditions: []v1alpha1.ApplicationCondition{ + { + Type: v1alpha1.ApplicationConditionSyncError, + Message: syncTaskUnsuccessfullErrorMessage, + }, + }, + OperationState: &v1alpha1.OperationState{ + SyncResult: &v1alpha1.SyncOperationResult{ + Resources: v1alpha1.ResourceResults{ + &v1alpha1.ResourceResult{ + Kind: "Job", + Name: "some-job", + Message: "job failed", + HookPhase: common.OperationFailed, + }, + &v1alpha1.ResourceResult{ + Kind: "Pod", + Name: "some-pod", + Message: "pod failed", + Status: common.ResultCodeSyncFailed, + }, + &v1alpha1.ResourceResult{ + Kind: "Job", + Name: "some-succeeded-hook", + Message: "job succeeded", + HookPhase: common.OperationSucceeded, + }, + &v1alpha1.ResourceResult{ + Kind: "Pod", + Name: "synced-pod", + Message: "pod synced", + Status: common.ResultCodeSynced, + }, + }, + }, + }, + }) + + assert.Len(t, errors, 2) + assert.Equal(t, fmt.Sprintf("Resource %s(%s): \n %s", "Job", "some-job", "job failed"), errors[0].Message) + assert.Equal(t, "sync", errors[0].Type) + assert.Equal(t, "error", errors[0].Level) + assert.Equal(t, fmt.Sprintf("Resource %s(%s): \n %s", "Pod", "some-pod", "pod failed"), errors[1].Message) + assert.Equal(t, "sync", errors[1].Type) + assert.Equal(t, "error", errors[1].Level) + }) +} + +func TestParseAggregativeHealthErrors(t *testing.T) { + t.Run("application tree is nil", func(t *testing.T) { + errs := parseAggregativeHealthErrors(&v1alpha1.ResourceStatus{ + Group: "group", + Kind: "application", + Namespace: "namespace", + Name: "name", + }, nil, false) + assert.Empty(t, errs) + }) + + t.Run("should set sourceReference", func(t *testing.T) { + rsName := "test-deployment" + ns := "test" + errMessage := "backoff pulling image test/test:0.1" + rsRef := v1alpha1.ResourceRef{ + Group: "g", + Version: "v", + Kind: "ReplicaSet", + Name: rsName + "1", + Namespace: ns, + } + + deployRef := v1alpha1.ResourceRef{ + Group: "g", + Version: "v", + Kind: "Deployment", + Name: rsName, + Namespace: ns, + } + + appTree := v1alpha1.ApplicationTree{ + Nodes: []v1alpha1.ResourceNode{ + { // Pod + Health: &v1alpha1.HealthStatus{ + Status: health.HealthStatusDegraded, + Message: errMessage, + }, + ResourceRef: v1alpha1.ResourceRef{ + Group: "g", + Version: "v", + Kind: "Pod", + Name: rsName + "1-3n235j5", + Namespace: ns, + }, + ParentRefs: []v1alpha1.ResourceRef{rsRef}, + CreatedAt: &metav1.Time{ + Time: time.Now(), + }, + }, + { // ReplicaSet + Health: &v1alpha1.HealthStatus{ + Status: health.HealthStatusProgressing, + Message: "", + }, + ResourceRef: rsRef, + ParentRefs: []v1alpha1.ResourceRef{deployRef}, + CreatedAt: &metav1.Time{ + Time: time.Now(), + }, + }, + { // Deployment + Health: &v1alpha1.HealthStatus{ + Status: health.HealthStatusDegraded, + Message: "", + }, + ResourceRef: deployRef, + ParentRefs: []v1alpha1.ResourceRef{}, + CreatedAt: &metav1.Time{ + Time: time.Now(), + }, + }, + }, + } + + errs := parseAggregativeHealthErrors(&v1alpha1.ResourceStatus{ + Group: deployRef.Group, + Version: deployRef.Version, + Kind: deployRef.Kind, + Name: deployRef.Name, + Namespace: deployRef.Namespace, + }, &appTree, true) + assert.Len(t, errs, 1) + assert.Equal(t, errMessage, errs[0].Message) + assert.NotNil(t, errs[0].SourceReference) + assert.Equal(t, deployRef.Name, errs[0].SourceReference.Name) + }) + + t.Run("should build error from root node if it's degraded while no one of child in degraded health state", func(t *testing.T) { + rsName := "test-deployment" + ns := "test" + errMessage := "backoff pulling image test/test:0.1" + replicaSetRef := v1alpha1.ResourceRef{ + Group: "g", + Version: "v", + Kind: "ReplicaSet", + Name: rsName + "1", + Namespace: ns, + } + + deploymentRef := v1alpha1.ResourceRef{ + Group: "g", + Version: "v", + Kind: "Deployment", + Name: rsName, + Namespace: ns, + } + + appTree := v1alpha1.ApplicationTree{ + Nodes: []v1alpha1.ResourceNode{ + { // Pod + ResourceRef: v1alpha1.ResourceRef{ + Group: "g", + Version: "v", + Kind: "Pod", + Name: rsName + "1-3n235j5", + Namespace: ns, + }, + Health: &v1alpha1.HealthStatus{ + Status: health.HealthStatusProgressing, + Message: "some error of pod", + }, + ParentRefs: []v1alpha1.ResourceRef{replicaSetRef}, + CreatedAt: &metav1.Time{ + Time: time.Now(), + }, + }, + { // ReplicaSet + ResourceRef: replicaSetRef, + Health: &v1alpha1.HealthStatus{ + Status: health.HealthStatusProgressing, + Message: "", + }, + ParentRefs: []v1alpha1.ResourceRef{deploymentRef}, + CreatedAt: &metav1.Time{ + Time: time.Now(), + }, + }, + { // Deployment + ResourceRef: deploymentRef, + Health: &v1alpha1.HealthStatus{ + Status: health.HealthStatusDegraded, + Message: errMessage, + }, + ParentRefs: []v1alpha1.ResourceRef{}, + CreatedAt: &metav1.Time{ + Time: time.Now(), + }, + }, + }, + } + + errs := parseAggregativeHealthErrors(&v1alpha1.ResourceStatus{ + Group: deploymentRef.Group, + Version: deploymentRef.Version, + Kind: deploymentRef.Kind, + Name: deploymentRef.Name, + Namespace: deploymentRef.Namespace, + }, &appTree, true) + assert.Len(t, errs, 1) + assert.Equal(t, errMessage, errs[0].Message) + assert.NotNil(t, errs[0].SourceReference) + assert.Equal(t, deploymentRef.Name, errs[0].SourceReference.Name) + }) +} diff --git a/event_reporter/reporter/broadcaster.go b/event_reporter/reporter/broadcaster.go new file mode 100644 index 0000000000000..fd46e1027ac42 --- /dev/null +++ b/event_reporter/reporter/broadcaster.go @@ -0,0 +1,156 @@ +package reporter + +import ( + "math" + "sync" + + log "github.com/sirupsen/logrus" + "k8s.io/apimachinery/pkg/watch" + + argocommon "github.com/argoproj/argo-cd/v2/common" + "github.com/argoproj/argo-cd/v2/event_reporter/metrics" + "github.com/argoproj/argo-cd/v2/event_reporter/sharding" + appv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/util/env" +) + +type subscriber struct { + ch chan *appv1.ApplicationWatchEvent + filters []func(*appv1.ApplicationWatchEvent) bool +} + +func (s *subscriber) matches(event *appv1.ApplicationWatchEvent) bool { + for i := range s.filters { + if !s.filters[i](event) { + return false + } + } + return true +} + +// Broadcaster is an interface for broadcasting application informer watch events to multiple subscribers. +type Broadcaster interface { + Subscribe(ch chan *appv1.ApplicationWatchEvent, filters ...func(event *appv1.ApplicationWatchEvent) bool) func() + OnAdd(interface{}, bool) + OnUpdate(interface{}, interface{}) + OnDelete(interface{}) +} + +type broadcasterHandler struct { + lock sync.Mutex + subscribers []*subscriber + filter sharding.ApplicationFilterFunction + featureManager *FeatureManager + metricsServer *metrics.MetricsServer + rateLimiter *RateLimiter +} + +func NewBroadcaster(featureManager *FeatureManager, metricsServer *metrics.MetricsServer, rateLimiterOpts *RateLimiterOpts) Broadcaster { + // todo: pass real value here + filter := getApplicationFilter("") + rl := NewRateLimiter(rateLimiterOpts) + return &broadcasterHandler{ + filter: filter, + featureManager: featureManager, + metricsServer: metricsServer, + rateLimiter: rl, + } +} + +func (b *broadcasterHandler) notify(event *appv1.ApplicationWatchEvent) { + // Make a local copy of b.subscribers, then send channel events outside the lock, + // to avoid data race on b.subscribers changes + subscribers := []*subscriber{} + b.lock.Lock() + subscribers = append(subscribers, b.subscribers...) + b.lock.Unlock() + + if b.filter != nil { + result, expectedShard := b.filter(&event.Application) + if !result { + log.Infof("filtering application '%s', wrong shard, should be %d", event.Application.Name, expectedShard) + return + } + } + + for _, s := range subscribers { + if s.matches(event) { + limited, err, learningMode := b.rateLimiter.Limit(event.Application.Name) + errorInLearningMode := learningMode && err != nil + if err != nil || limited { + log.Errorf("adding application '%s' to channel failed, due to rate limit, learningMode %t", event.Application.Name, learningMode) + // if learning mode is enabled, we will continue to send events + if !learningMode { + b.metricsServer.IncDroppedEventsCounter(event.Application.Name, false) + continue + } + } + + select { + case s.ch <- event: + { + log.Infof("adding application '%s' to channel", event.Application.Name) + b.metricsServer.IncEnqueuedEventsCounter(event.Application.Name, errorInLearningMode) + } + default: + // drop event if cannot send right away + log.WithField("application", event.Application.Name).Warn("unable to send event notification") + b.metricsServer.IncDroppedEventsCounter(event.Application.Name, errorInLearningMode) + } + } + } +} + +// Subscribe forward application informer watch events to the provided channel. +// The watch events are dropped if no receives are reading events from the channel so the channel must have +// buffer if dropping events is not acceptable. +func (b *broadcasterHandler) Subscribe(ch chan *appv1.ApplicationWatchEvent, filters ...func(event *appv1.ApplicationWatchEvent) bool) func() { + b.lock.Lock() + defer b.lock.Unlock() + subscriber := &subscriber{ch, filters} + b.subscribers = append(b.subscribers, subscriber) + return func() { + b.lock.Lock() + defer b.lock.Unlock() + for i := range b.subscribers { + if b.subscribers[i] == subscriber { + b.subscribers = append(b.subscribers[:i], b.subscribers[i+1:]...) + break + } + } + } +} + +func (b *broadcasterHandler) OnAdd(obj interface{}, _ bool) { + if app, ok := obj.(*appv1.Application); ok { + b.notify(&appv1.ApplicationWatchEvent{Application: *app, Type: watch.Added}) + } +} + +func (b *broadcasterHandler) OnUpdate(_, newObj interface{}) { + if app, ok := newObj.(*appv1.Application); ok { + b.notify(&appv1.ApplicationWatchEvent{Application: *app, Type: watch.Modified}) + } +} + +func (b *broadcasterHandler) OnDelete(obj interface{}) { + if app, ok := obj.(*appv1.Application); ok { + b.notify(&appv1.ApplicationWatchEvent{Application: *app, Type: watch.Deleted}) + } +} + +func getApplicationFilter(shardingAlgorithm string) sharding.ApplicationFilterFunction { + shardingSvc := sharding.NewSharding() + replicas := env.ParseNumFromEnv(argocommon.EnvEventReporterReplicas, 0, 0, math.MaxInt32) + var applicationFilter func(app *appv1.Application) (bool, int) + if replicas > 1 { + shard := sharding.GetShardNumber() + log.Infof("Processing applications from shard %d", shard) + log.Infof("Using filter function: %s", shardingAlgorithm) + distributionFunction := shardingSvc.GetDistributionFunction(shardingAlgorithm) + applicationFilter = shardingSvc.GetApplicationFilter(distributionFunction, shard) + } else { + log.Info("Processing all application shards") + } + return applicationFilter +} diff --git a/event_reporter/reporter/event_payload.go b/event_reporter/reporter/event_payload.go new file mode 100644 index 0000000000000..24d7cbd465011 --- /dev/null +++ b/event_reporter/reporter/event_payload.go @@ -0,0 +1,387 @@ +package reporter + +import ( + "context" + "encoding/json" + "fmt" + "strings" + + "github.com/argoproj/argo-cd/v2/event_reporter/utils" + "github.com/argoproj/argo-cd/v2/pkg/apiclient/application" + "github.com/argoproj/argo-cd/v2/pkg/apiclient/events" + appv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/reposerver/apiclient" + + "github.com/argoproj/gitops-engine/pkg/health" + log "github.com/sirupsen/logrus" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "sigs.k8s.io/yaml" +) + +func getResourceEventPayload( + appEventProcessingStartedAt string, + rr *ReportedResource, + reportedEntityParentApp *ReportedEntityParentApp, + argoTrackingMetadata *ArgoTrackingMetadata, + runtimeVersion string, +) (*events.Event, error) { + var ( + err error + syncStarted = metav1.Now() + syncFinished *metav1.Time + logCtx *log.Entry + ) + + if rr.rsAsAppInfo != nil && rr.rsAsAppInfo.app != nil { + logCtx = log.WithField("application", rr.rsAsAppInfo.app.Name) + } else { + logCtx = log.NewEntry(log.StandardLogger()) + } + + object := []byte(*rr.actualState.Manifest) + + if rr.rsAsAppInfo != nil && rr.rsAsAppInfo.revisionsMetadata != nil && len(object) != 0 { + actualObject, err := appv1.UnmarshalToUnstructured(*rr.actualState.Manifest) + if err != nil { + return nil, fmt.Errorf("failed to unmarshal manifest: %w", err) + } + + object, err = addCommitDetailsToUnstructured(actualObject, rr) + if err != nil { + return nil, err + } + } + if len(object) == 0 { + if len(rr.desiredState.CompiledManifest) == 0 { + object, err = buildEventObjectAsLiveAndCompiledManifestsEmpty(rr) + if err != nil { + return nil, err + } + } else { + object, err = useCompiledManifestAsEventObject(rr) + if err != nil { + return nil, err + } + } + } else if rr.rs.RequiresPruning && !rr.manifestGenErr { + // resource should be deleted + makeDesiredAndLiveManifestEmpty(rr.actualState, rr.desiredState) + } + + if (rr.rsAsAppInfo != nil && rr.rsAsAppInfo.app != nil && rr.rsAsAppInfo.app.DeletionTimestamp != nil) || reportedEntityParentApp.app.ObjectMeta.DeletionTimestamp != nil { + // resource should be deleted in case if application in process of deletion + makeDesiredAndLiveManifestEmpty(rr.actualState, rr.desiredState) + } + + if len(rr.desiredState.RawManifest) == 0 && len(rr.desiredState.CompiledManifest) != 0 { + // for handling helm defined resources, etc... + y, err := yaml.JSONToYAML([]byte(rr.desiredState.CompiledManifest)) + if err == nil { + rr.desiredState.RawManifest = string(y) + } + } + + if reportedEntityParentApp.app.Status.OperationState != nil { + syncStarted = reportedEntityParentApp.app.Status.OperationState.StartedAt + syncFinished = reportedEntityParentApp.app.Status.OperationState.FinishedAt + } + + // for primitive resources that are synced right away and don't require progression time (like configmap) + if rr.rs.Status == appv1.SyncStatusCodeSynced && rr.rs.Health != nil && rr.rs.Health.Status == health.HealthStatusHealthy { + syncFinished = &syncStarted + } + + var applicationVersionsEvents *events.ApplicationVersions + if rr.rsAsAppInfo != nil { + applicationVersionsEvents, err = utils.RepoAppVersionsToEvent(rr.rsAsAppInfo.applicationVersions) + if err != nil { + logCtx.Errorf("failed to convert appVersions: %v", err) + } + } + + source := events.ObjectSource{ + DesiredManifest: rr.desiredState.CompiledManifest, + ActualManifest: *rr.actualState.Manifest, + GitManifest: rr.desiredState.RawManifest, + Path: rr.desiredState.Path, + Revision: utils.GetApplicationLatestRevision(reportedEntityParentApp.app), + Revisions: utils.GetApplicationLatestRevisions(reportedEntityParentApp.app), + OperationSyncRevision: utils.GetOperationRevision(reportedEntityParentApp.app), + OperationSyncRevisions: utils.GetOperationRevisions(reportedEntityParentApp.app), + HistoryId: utils.GetLatestAppHistoryId(reportedEntityParentApp.app), + AppName: reportedEntityParentApp.app.Name, + AppNamespace: reportedEntityParentApp.app.Namespace, + AppUID: string(reportedEntityParentApp.app.ObjectMeta.UID), + AppLabels: reportedEntityParentApp.app.Labels, + SyncStatus: string(rr.rs.Status), + SyncStartedAt: syncStarted, + SyncFinishedAt: syncFinished, + Cluster: reportedEntityParentApp.app.Spec.Destination.Server, + AppInstanceLabelKey: *argoTrackingMetadata.AppInstanceLabelKey, + TrackingMethod: string(*argoTrackingMetadata.TrackingMethod), + AppMultiSourced: reportedEntityParentApp.app.Spec.HasMultipleSources(), + AppSourceIdx: rr.appSourceIdx, + } + + source.RepoURL = getResourceSourceRepoUrl(rr, reportedEntityParentApp) + addResourceEventPayloadGitCommitDetails(&source, rr, reportedEntityParentApp) + + if reportedEntityParentApp.validatedDestination != nil { + source.ClusterName = &reportedEntityParentApp.validatedDestination.Name + } + + if rr.rs.Health != nil { + source.HealthStatus = (*string)(&rr.rs.Health.Status) + source.HealthMessage = &rr.rs.Health.Message + } + + payload := events.EventPayload{ + Timestamp: appEventProcessingStartedAt, + Object: object, + Source: &source, + Errors: getResourceEventPayloadErrors(rr, reportedEntityParentApp), + AppVersions: applicationVersionsEvents, + RuntimeVersion: runtimeVersion, + } + + if payload.AppVersions != nil { + logCtx.Infof("AppVersion before encoding: %v", utils.SafeString(payload.AppVersions.AppVersion)) + } + + payloadBytes, err := json.Marshal(&payload) + if err != nil { + return nil, fmt.Errorf("failed to marshal payload for resource %s/%s: %w", rr.rs.Namespace, rr.rs.Name, err) + } + + return &events.Event{Payload: payloadBytes}, nil +} + +func getResourceSourceRepoUrl( + rr *ReportedResource, + reportedEntityParentApp *ReportedEntityParentApp, +) string { + specCopy := reportedEntityParentApp.app.Spec.DeepCopy() + + specCopy.Sources = reportedEntityParentApp.app.Status.Sync.ComparedTo.Sources + specCopy.Source = reportedEntityParentApp.app.Status.Sync.ComparedTo.Source.DeepCopy() + + if specCopy.HasMultipleSources() { + if !rr.appSourceIdxDetected() { + return "" + } + source := specCopy.GetSourcePtrByIndex(int(rr.appSourceIdx)) + if source == nil { + return "" + } + return source.RepoURL + } + + return specCopy.Source.RepoURL +} + +func addResourceEventPayloadGitCommitDetails( + source *events.ObjectSource, + rr *ReportedResource, + reportedEntityParentApp *ReportedEntityParentApp, +) { + if reportedEntityParentApp.revisionsMetadata == nil || reportedEntityParentApp.revisionsMetadata.SyncRevisions == nil || rr.appSourceIdx == -1 { + return + } + + syncRevisionWithMetadata := reportedEntityParentApp.revisionsMetadata.GetSyncRevisionAt(int(rr.appSourceIdx)) + + if syncRevisionWithMetadata != nil && syncRevisionWithMetadata.Metadata != nil { + source.CommitMessage = syncRevisionWithMetadata.Metadata.Message + source.CommitAuthor = syncRevisionWithMetadata.Metadata.Author + source.CommitDate = &syncRevisionWithMetadata.Metadata.Date + } +} + +func getResourceEventPayloadErrors( + rr *ReportedResource, + reportedEntityParentApp *ReportedEntityParentApp, +) []*events.ObjectError { + var errors []*events.ObjectError + + if reportedEntityParentApp.app.Status.OperationState != nil { + errors = append(errors, parseResourceSyncResultErrors(rr.rs, reportedEntityParentApp.app.Status.OperationState)...) + } + + // parent application not include errors in application originally was created with broken state, for example in destination missed namespace + if rr.rsAsAppInfo != nil && rr.rsAsAppInfo.app != nil { + if rr.rsAsAppInfo.app.Status.OperationState != nil { + errors = append(errors, parseApplicationSyncResultErrors(rr.rsAsAppInfo.app.Status.OperationState)...) + } + + if rr.rsAsAppInfo.app.Status.Conditions != nil { + errors = append(errors, parseApplicationSyncResultErrorsFromConditions(rr.rsAsAppInfo.app.Status)...) + } + + errors = append(errors, parseAggregativeHealthErrorsOfApplication(rr.rsAsAppInfo.app, reportedEntityParentApp.appTree)...) + } + + if rr.rs.Health != nil && rr.rs.Health.Status != health.HealthStatusHealthy { + errors = append(errors, parseAggregativeHealthErrors(rr.rs, reportedEntityParentApp.appTree, false)...) + } + + return errors +} + +func useCompiledManifestAsEventObject( + rr *ReportedResource, +) ([]byte, error) { + // no actual state, use desired state as event object + unstructuredWithNamespace, err := utils.AddDestNamespaceToManifest([]byte(rr.desiredState.CompiledManifest), rr.rs) + if err != nil { + return nil, fmt.Errorf("failed to add destination namespace to manifest: %w", err) + } + + return addCommitDetailsToUnstructured(unstructuredWithNamespace, rr) +} + +func buildEventObjectAsLiveAndCompiledManifestsEmpty( + rr *ReportedResource, +) ([]byte, error) { + // no actual or desired state, don't send event + u := &unstructured.Unstructured{} + + u.SetAPIVersion(rr.GetApiVersion()) + u.SetKind(rr.rs.Kind) + u.SetName(rr.rs.Name) + u.SetNamespace(rr.rs.Namespace) + + return addCommitDetailsToUnstructured(u, rr) +} + +// when empty minifests reported to codefresh they will get deleted +func makeDesiredAndLiveManifestEmpty( + actualState *application.ApplicationResourceResponse, + desiredState *apiclient.Manifest, +) { + // resource should be deleted + desiredState.CompiledManifest = "" + manifest := "" + actualState.Manifest = &manifest +} + +func addCommitDetailsToUnstructured( + u *unstructured.Unstructured, + rr *ReportedResource, +) ([]byte, error) { + if rr.rsAsAppInfo != nil && rr.rsAsAppInfo.revisionsMetadata != nil { + u = utils.AddCommitsDetailsToAnnotations(u, rr.rsAsAppInfo.revisionsMetadata) + if rr.rsAsAppInfo.app != nil { + u = utils.AddCommitDetailsToLabels(u, getApplicationLegacyRevisionDetails(rr.rsAsAppInfo.app, rr.rsAsAppInfo.revisionsMetadata)) + } + } + + object, err := u.MarshalJSON() + if err != nil { + return nil, fmt.Errorf("failed to marshal unstructured object: %w", err) + } + + return object, err +} + +func (s *applicationEventReporter) getApplicationEventPayload( + ctx context.Context, + a *appv1.Application, + appTree *appv1.ApplicationTree, + eventProcessingStartedAt string, + applicationVersions *apiclient.ApplicationVersions, + argoTrackingMetadata *ArgoTrackingMetadata, + runtimeVersion string, +) (*events.Event, error) { + var ( + syncStarted = metav1.Now() + syncFinished *metav1.Time + logCtx = log.WithField("application", a.Name) + errors = []*events.ObjectError{} + ) + + obj := appv1.Application{} + a.DeepCopyInto(&obj) + + // make sure there is type meta on object + obj.SetDefaultTypeMeta() + + if a.Status.OperationState != nil { + syncStarted = a.Status.OperationState.StartedAt + syncFinished = a.Status.OperationState.FinishedAt + } + + revisionsMetadata, err := s.getApplicationRevisionsMetadata(ctx, logCtx, a) + if err != nil { + if !strings.Contains(err.Error(), "not found") { + return nil, fmt.Errorf("failed to get revision metadata: %w", err) + } + + logCtx.Warnf("failed to get revision metadata: %s, reporting application deletion event", err.Error()) + } + + utils.AddCommitsDetailsToAppAnnotations(obj, revisionsMetadata) + utils.AddCommitsDetailsToAppLabels(&obj, getApplicationLegacyRevisionDetails(&obj, revisionsMetadata)) + + object, err := json.Marshal(&obj) + if err != nil { + return nil, fmt.Errorf("failed to marshal application event") + } + + actualManifest := string(object) + if a.DeletionTimestamp != nil { + actualManifest = "" // mark as deleted + logCtx.Info("reporting application deletion event") + } + + applicationVersionsEvents, err := utils.RepoAppVersionsToEvent(applicationVersions) + if err != nil { + logCtx.Errorf("failed to convert appVersions: %v", err) + } + + hs := string(a.Status.Health.Status) + source := &events.ObjectSource{ + DesiredManifest: "", + GitManifest: "", + ActualManifest: actualManifest, + RepoURL: a.Spec.GetSource().RepoURL, + CommitMessage: "", + CommitAuthor: "", + Path: "", + Revision: "", + OperationSyncRevision: "", + HistoryId: 0, + AppName: "", + AppUID: "", + AppLabels: map[string]string{}, + SyncStatus: string(a.Status.Sync.Status), + SyncStartedAt: syncStarted, + SyncFinishedAt: syncFinished, + HealthStatus: &hs, + HealthMessage: &a.Status.Health.Message, + Cluster: a.Spec.Destination.Server, + AppInstanceLabelKey: *argoTrackingMetadata.AppInstanceLabelKey, + TrackingMethod: string(*argoTrackingMetadata.TrackingMethod), + } + + errors = append(errors, parseApplicationSyncResultErrorsFromConditions(a.Status)...) + errors = append(errors, parseAggregativeHealthErrorsOfApplication(a, appTree)...) + + payload := events.EventPayload{ + Timestamp: eventProcessingStartedAt, + Object: object, + Source: source, + Errors: errors, + AppVersions: applicationVersionsEvents, + RuntimeVersion: runtimeVersion, + } + + logCtx.Infof("AppVersion before encoding: %v", utils.SafeString(payload.AppVersions.AppVersion)) + + payloadBytes, err := json.Marshal(&payload) + if err != nil { + return nil, fmt.Errorf("failed to marshal payload for resource %s/%s: %w", a.Namespace, a.Name, err) + } + + return &events.Event{Payload: payloadBytes}, nil +} diff --git a/event_reporter/reporter/event_payload_test.go b/event_reporter/reporter/event_payload_test.go new file mode 100644 index 0000000000000..d05cfd7f22774 --- /dev/null +++ b/event_reporter/reporter/event_payload_test.go @@ -0,0 +1,153 @@ +package reporter + +import ( + "encoding/json" + "testing" + + "github.com/argoproj/argo-cd/v2/event_reporter/utils" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + "github.com/argoproj/argo-cd/v2/common" + "github.com/argoproj/argo-cd/v2/pkg/apiclient/application" + "github.com/argoproj/argo-cd/v2/pkg/apiclient/events" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + repoApiclient "github.com/argoproj/argo-cd/v2/reposerver/apiclient" + "github.com/argoproj/argo-cd/v2/util/argo" +) + +func getMockedArgoTrackingMetadata() *ArgoTrackingMetadata { + appInstanceLabelKey := common.LabelKeyAppInstance + trackingMethod := argo.TrackingMethodLabel + installationID := "" + + return &ArgoTrackingMetadata{ + AppInstanceLabelKey: &appInstanceLabelKey, + TrackingMethod: &trackingMethod, + InstallationID: &installationID, + } +} + +func TestGetResourceEventPayload(t *testing.T) { + t.Run("Deleting timestamp is empty", func(t *testing.T) { + app := v1alpha1.Application{ + Spec: v1alpha1.ApplicationSpec{ + Source: &v1alpha1.ApplicationSource{ + RepoURL: "test", + }, + }, + } + rs := v1alpha1.ResourceStatus{} + + man := "{ \"key\" : \"manifest\" }" + + actualState := application.ApplicationResourceResponse{ + Manifest: &man, + } + desiredState := repoApiclient.Manifest{ + CompiledManifest: "{ \"key\" : \"manifest\" }", + } + appTree := v1alpha1.ApplicationTree{} + revisionMetadata := utils.AppSyncRevisionsMetadata{ + SyncRevisions: []*utils.RevisionWithMetadata{{ + Metadata: &v1alpha1.RevisionMetadata{ + Author: "demo usert", + Date: metav1.Time{}, + Message: "some message", + }, + }}, + } + + event, err := getResourceEventPayload("", &ReportedResource{ + rs: &rs, + actualState: &actualState, + desiredState: &desiredState, + manifestGenErr: true, + rsAsAppInfo: nil, + }, &ReportedEntityParentApp{ + app: &app, + appTree: &appTree, + revisionsMetadata: &revisionMetadata, + }, getMockedArgoTrackingMetadata(), "0.0.1") + require.NoError(t, err) + + var eventPayload events.EventPayload + + err = json.Unmarshal(event.Payload, &eventPayload) + require.NoError(t, err) + + assert.JSONEq(t, "{ \"key\" : \"manifest\" }", eventPayload.Source.DesiredManifest) + assert.JSONEq(t, "{ \"key\" : \"manifest\" }", eventPayload.Source.ActualManifest) + }) + + t.Run("Deleting timestamp not empty", func(t *testing.T) { + app := v1alpha1.Application{ + ObjectMeta: metav1.ObjectMeta{ + DeletionTimestamp: &metav1.Time{}, + }, + Status: v1alpha1.ApplicationStatus{}, + } + rs := v1alpha1.ResourceStatus{} + man := "{ \"key\" : \"manifest\" }" + actualState := application.ApplicationResourceResponse{ + Manifest: &man, + } + desiredState := repoApiclient.Manifest{ + CompiledManifest: "{ \"key\" : \"manifest\" }", + } + appTree := v1alpha1.ApplicationTree{} + revisionMetadata := utils.AppSyncRevisionsMetadata{ + SyncRevisions: []*utils.RevisionWithMetadata{}, + } + + event, err := getResourceEventPayload("", &ReportedResource{ + rs: &rs, + actualState: &actualState, + desiredState: &desiredState, + manifestGenErr: true, + rsAsAppInfo: nil, + }, &ReportedEntityParentApp{ + app: &app, + appTree: &appTree, + revisionsMetadata: &revisionMetadata, + }, getMockedArgoTrackingMetadata(), "0.0.1") + require.NoError(t, err) + + var eventPayload events.EventPayload + + err = json.Unmarshal(event.Payload, &eventPayload) + require.NoError(t, err) + + assert.Equal(t, "", eventPayload.Source.DesiredManifest) + assert.Equal(t, "", eventPayload.Source.ActualManifest) + }) +} + +func TestGetResourceEventPayloadWithoutRevision(t *testing.T) { + app := v1alpha1.Application{} + rs := v1alpha1.ResourceStatus{} + + mf := "{ \"key\" : \"manifest\" }" + + actualState := application.ApplicationResourceResponse{ + Manifest: &mf, + } + desiredState := repoApiclient.Manifest{ + CompiledManifest: "{ \"key\" : \"manifest\" }", + } + appTree := v1alpha1.ApplicationTree{} + + _, err := getResourceEventPayload("", &ReportedResource{ + rs: &rs, + actualState: &actualState, + desiredState: &desiredState, + manifestGenErr: true, + rsAsAppInfo: nil, + }, &ReportedEntityParentApp{ + app: &app, + appTree: &appTree, + }, getMockedArgoTrackingMetadata(), "0.0.1") + assert.NoError(t, err) +} diff --git a/event_reporter/reporter/feature_manager.go b/event_reporter/reporter/feature_manager.go new file mode 100644 index 0000000000000..bbfd34121736e --- /dev/null +++ b/event_reporter/reporter/feature_manager.go @@ -0,0 +1,13 @@ +package reporter + +import ( + settings_util "github.com/argoproj/argo-cd/v2/util/settings" +) + +type FeatureManager struct { + settingsMgr *settings_util.SettingsManager +} + +func NewFeatureManager(settingsMgr *settings_util.SettingsManager) *FeatureManager { + return &FeatureManager{settingsMgr: settingsMgr} +} diff --git a/event_reporter/reporter/rate_limiter.go b/event_reporter/reporter/rate_limiter.go new file mode 100644 index 0000000000000..dd4b4c4b4c663 --- /dev/null +++ b/event_reporter/reporter/rate_limiter.go @@ -0,0 +1,50 @@ +package reporter + +import ( + "context" + "time" + + "github.com/sethvargo/go-limiter" + "github.com/sethvargo/go-limiter/memorystore" +) + +type RateLimiterOpts struct { + Enabled bool + Rate time.Duration + Capacity int + LearningMode bool +} + +type RateLimiter struct { + opts *RateLimiterOpts + limiter limiter.Store +} + +func NewRateLimiter(opts *RateLimiterOpts) *RateLimiter { + store, err := memorystore.New(&memorystore.Config{ + Tokens: uint64(opts.Capacity), + Interval: opts.Rate, + }) + if err != nil { + return &RateLimiter{opts: opts, limiter: nil} + } + return &RateLimiter{opts: opts, limiter: store} +} + +func (rl *RateLimiter) Limit(applicationName string) (bool, error, bool) { + if !rl.opts.Enabled { + return false, nil, rl.opts.LearningMode + } + + if rl.limiter == nil { + // TODO: add warning log + return false, nil, rl.opts.LearningMode + } + + _, _, _, ok, err := rl.limiter.Take(context.Background(), applicationName) + if err != nil { + return false, err, rl.opts.LearningMode + } + + return !ok, nil, rl.opts.LearningMode +} diff --git a/event_reporter/reporter/rate_limiter_test.go b/event_reporter/reporter/rate_limiter_test.go new file mode 100644 index 0000000000000..24194d3ed4f81 --- /dev/null +++ b/event_reporter/reporter/rate_limiter_test.go @@ -0,0 +1,51 @@ +package reporter + +import ( + "testing" + "time" +) + +func TestRateLimiter(t *testing.T) { + t.Run("Limiter is turned off", func(t *testing.T) { + rl := NewRateLimiter(&RateLimiterOpts{ + Enabled: false, + }) + limit, err, _ := rl.Limit("foo") + if err != nil { + t.Errorf("Expected no error, got %v", err) + } + if limit { + t.Errorf("Should be no limited") + } + }) + t.Run("Limiter is turned on", func(t *testing.T) { + rl := NewRateLimiter(&RateLimiterOpts{ + Enabled: true, + Rate: time.Second, + Capacity: 1, + }) + limit, err, _ := rl.Limit("foo") + if err != nil { + t.Errorf("Expected no error, got %v", err) + } + if limit { + t.Errorf("Should be no limited") + } + }) + t.Run("Limiter is turned on but with 0 capacity", func(t *testing.T) { + rl := NewRateLimiter(&RateLimiterOpts{ + Enabled: true, + Rate: time.Second, + Capacity: 1, + }) + limit, _, _ := rl.Limit("foo") + if limit { + t.Errorf("Expected no limit, got nil") + } + + limit, _, _ = rl.Limit("foo") + if !limit { + t.Errorf("Expected limit, got nil") + } + }) +} diff --git a/event_reporter/reporter/resource_utils.go b/event_reporter/reporter/resource_utils.go new file mode 100644 index 0000000000000..f652203d808b8 --- /dev/null +++ b/event_reporter/reporter/resource_utils.go @@ -0,0 +1,90 @@ +package reporter + +import ( + "encoding/json" + + appsv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + + appv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" +) + +type ResourceTypeKey struct { + Group string + Kind string +} + +var allowedResourceTypes = map[ResourceTypeKey]bool{ + // Kubernetes core resources + {Group: appsv1.GroupName, Kind: "ReplicaSet"}: true, + {Group: appsv1.GroupName, Kind: "Deployment"}: true, + {Group: appsv1.GroupName, Kind: "StatefulSet"}: true, + {Group: corev1.GroupName, Kind: "Service"}: true, + {Group: corev1.GroupName, Kind: "ConfigMap"}: true, + + // Argo CD resources + {Group: "argoproj.io", Kind: "Application"}: true, + {Group: "argoproj.io", Kind: "ApplicationSet"}: true, + + // Argo Rollouts resources + {Group: "argoproj.io", Kind: "Rollout"}: true, + {Group: "argoproj.io", Kind: "AnalysisRun"}: true, + + // Argo Workflows resources + {Group: "argoproj.io", Kind: "Workflow"}: true, + {Group: "argoproj.io", Kind: "WorkflowTemplate"}: true, + {Group: "argoproj.io", Kind: "ClusterWorkflowTemplate"}: true, + + // Argo Events resources + {Group: "argoproj.io", Kind: "Sensor"}: true, + {Group: "argoproj.io", Kind: "EventSource"}: true, + + // Codefresh resources + {Group: "codefresh.io", Kind: "Product"}: true, + {Group: "codefresh.io", Kind: "PromotionFlow"}: true, + {Group: "codefresh.io", Kind: "PromotionPolicy"}: true, + {Group: "codefresh.io", Kind: "PromotionTemplate"}: true, + {Group: "codefresh.io", Kind: "RestrictedGitSource"}: true, + + // Bitnami resources + {Group: "bitnami.com", Kind: "SealedSecret"}: true, +} + +const ( + CODEFRESH_IO_ENTITY = "codefresh.io/entity" + CODEFRESH_IO_ENTITY_ALT = "codefresh_io_entity" + CODEFRESH_CM_NAME = "codefresh-cm" +) + +func isAllowedResource(rs appv1.ResourceStatus) bool { + gvk := rs.GroupVersionKind() + resourceKey := ResourceTypeKey{ + Group: gvk.Group, + Kind: gvk.Kind, + } + + return allowedResourceTypes[resourceKey] +} + +func isAllowedConfigMap(manifest string) bool { + var u unstructured.Unstructured + if err := json.Unmarshal([]byte(manifest), &u); err != nil { + return false + } + + // Check if it's the codefresh-cm + if u.GetName() == CODEFRESH_CM_NAME { + return true + } + + // Check for both possible Codefresh entity label formats + labels := u.GetLabels() + if labels == nil { + return false + } + + _, hasUnderscoreLabel := labels[CODEFRESH_IO_ENTITY] + _, hasDotLabel := labels[CODEFRESH_IO_ENTITY_ALT] + return hasUnderscoreLabel || hasDotLabel +} diff --git a/event_reporter/reporter/types.go b/event_reporter/reporter/types.go new file mode 100644 index 0000000000000..05c3fea4ae970 --- /dev/null +++ b/event_reporter/reporter/types.go @@ -0,0 +1,50 @@ +package reporter + +import ( + "github.com/argoproj/argo-cd/v2/event_reporter/utils" + "github.com/argoproj/argo-cd/v2/pkg/apiclient/application" + appv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/reposerver/apiclient" +) + +type ReportedResource struct { + rs *appv1.ResourceStatus + rsAsAppInfo *ReportedResourceAsApp // passed if resource is application + appSourceIdx int32 + actualState *application.ApplicationResourceResponse + desiredState *apiclient.Manifest + manifestGenErr bool +} + +type ReportedResourceAsApp struct { + app *appv1.Application + revisionsMetadata *utils.AppSyncRevisionsMetadata + applicationVersions *apiclient.ApplicationVersions +} + +type ReportedEntityParentApp struct { + app *appv1.Application + appTree *appv1.ApplicationTree + revisionsMetadata *utils.AppSyncRevisionsMetadata + validatedDestination *appv1.ApplicationDestination // with resolved Server url field if server Name used + desiredManifests *apiclient.ManifestResponse +} + +type ArgoTrackingMetadata struct { + AppInstanceLabelKey *string + TrackingMethod *appv1.TrackingMethod + InstallationID *string +} + +func (rr *ReportedResource) GetApiVersion() string { + apiVersion := rr.rs.Version + if rr.rs.Group != "" { + apiVersion = rr.rs.Group + "/" + rr.rs.Version + } + + return apiVersion +} + +func (rr *ReportedResource) appSourceIdxDetected() bool { + return rr.appSourceIdx >= 0 +} diff --git a/event_reporter/server.go b/event_reporter/server.go new file mode 100644 index 0000000000000..3bf7132bf0830 --- /dev/null +++ b/event_reporter/server.go @@ -0,0 +1,306 @@ +package event_reporter + +import ( + "context" + "crypto/tls" + "fmt" + "net" + "net/http" + "os" + "strings" + "time" + + "github.com/argoproj/argo-cd/v2/pkg/sources_server_client" + + appclient "github.com/argoproj/argo-cd/v2/event_reporter/application" + "github.com/argoproj/argo-cd/v2/event_reporter/reporter" + + "github.com/redis/go-redis/v9" + log "github.com/sirupsen/logrus" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/wait" + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/tools/cache" + + "github.com/argoproj/argo-cd/v2/common" + event_reporter "github.com/argoproj/argo-cd/v2/event_reporter/controller" + "github.com/argoproj/argo-cd/v2/event_reporter/handlers" + "github.com/argoproj/argo-cd/v2/event_reporter/metrics" + appclientset "github.com/argoproj/argo-cd/v2/pkg/client/clientset/versioned" + appinformer "github.com/argoproj/argo-cd/v2/pkg/client/informers/externalversions" + applisters "github.com/argoproj/argo-cd/v2/pkg/client/listers/application/v1alpha1" + codefresh "github.com/argoproj/argo-cd/v2/pkg/codefresh" + repoapiclient "github.com/argoproj/argo-cd/v2/reposerver/apiclient" + servercache "github.com/argoproj/argo-cd/v2/server/cache" + "github.com/argoproj/argo-cd/v2/server/rbacpolicy" + "github.com/argoproj/argo-cd/v2/server/repository" + "github.com/argoproj/argo-cd/v2/util/assets" + "github.com/argoproj/argo-cd/v2/util/db" + errorsutil "github.com/argoproj/argo-cd/v2/util/errors" + "github.com/argoproj/argo-cd/v2/util/healthz" + "github.com/argoproj/argo-cd/v2/util/io" + "github.com/argoproj/argo-cd/v2/util/rbac" + settings_util "github.com/argoproj/argo-cd/v2/util/settings" +) + +const ( + // catches corrupted informer state; see https://github.com/argoproj/argo-cd/issues/4960 for more information + notObjectErrMsg = "object does not implement the Object interfaces" +) + +var backoff = wait.Backoff{ + Steps: 5, + Duration: 500 * time.Millisecond, + Factor: 1.0, + Jitter: 0.1, +} + +type EventReporterServer struct { + EventReporterServerOpts + + settings *settings_util.ArgoCDSettings + log *log.Entry + settingsMgr *settings_util.SettingsManager + enf *rbac.Enforcer + projInformer cache.SharedIndexInformer + projLister applisters.AppProjectNamespaceLister + policyEnforcer *rbacpolicy.RBACPolicyEnforcer + appInformer cache.SharedIndexInformer + appLister applisters.ApplicationLister + db db.ArgoDB + + // stopCh is the channel which when closed, will shutdown the Event Reporter server + stopCh chan struct{} + serviceSet *EventReporterServerSet + featureManager *reporter.FeatureManager +} + +type EventReporterServerSet struct { + RepoService *repository.Server + MetricsServer *metrics.MetricsServer +} + +type EventReporterServerOpts struct { + ListenPort int + ListenHost string + MetricsPort int + MetricsHost string + Namespace string + KubeClientset kubernetes.Interface + AppClientset appclientset.Interface + RepoClientset repoapiclient.Clientset + ApplicationServiceClient appclient.ApplicationClient + Cache *servercache.Cache + RedisClient *redis.Client + ApplicationNamespaces []string + BaseHRef string + RootPath string + CodefreshConfig *codefresh.CodefreshConfig + RateLimiterOpts *reporter.RateLimiterOpts + UseSourcesServer bool + SourcesServerConfig *sources_server_client.SourcesServerConfig +} + +type handlerSwitcher struct { + handler http.Handler + urlToHandler map[string]http.Handler + contentTypeToHandler map[string]http.Handler +} + +type Listeners struct { + Main net.Listener + Metrics net.Listener +} + +func (l *Listeners) Close() error { + if l.Main != nil { + if err := l.Main.Close(); err != nil { + return err + } + l.Main = nil + } + if l.Metrics != nil { + if err := l.Metrics.Close(); err != nil { + return err + } + l.Metrics = nil + } + return nil +} + +func (s *handlerSwitcher) ServeHTTP(w http.ResponseWriter, r *http.Request) { + if urlHandler, ok := s.urlToHandler[r.URL.Path]; ok { + urlHandler.ServeHTTP(w, r) + } else if contentHandler, ok := s.contentTypeToHandler[r.Header.Get("content-type")]; ok { + contentHandler.ServeHTTP(w, r) + } else { + s.handler.ServeHTTP(w, r) + } +} + +func (a *EventReporterServer) healthCheck(r *http.Request) error { + if val, ok := r.URL.Query()["full"]; ok && len(val) > 0 && val[0] == "true" { + argoDB := db.NewDB(a.Namespace, a.settingsMgr, a.KubeClientset) + _, err := argoDB.ListClusters(r.Context()) + if err != nil && strings.Contains(err.Error(), notObjectErrMsg) { + return err + } + } + return nil +} + +// Init starts informers used by the API server +func (a *EventReporterServer) Init(ctx context.Context) { + go a.appInformer.Run(ctx.Done()) + svcSet := newEventReporterServiceSet(a) + a.serviceSet = svcSet +} + +func (a *EventReporterServer) RunController(ctx context.Context) { + controller := event_reporter.NewEventReporterController(a.appInformer, a.Cache, a.settingsMgr, a.ApplicationServiceClient, a.appLister, a.CodefreshConfig, a.serviceSet.MetricsServer, a.featureManager, a.RateLimiterOpts, a.db, a.UseSourcesServer, a.SourcesServerConfig) + go controller.Run(ctx) +} + +// newHTTPServer returns the HTTP server to serve HTTP/HTTPS requests. This is implemented +// using grpc-gateway as a proxy to the gRPC server. +func (a *EventReporterServer) newHTTPServer(ctx context.Context, port int) *http.Server { //nolint:golint,unparam + endpoint := fmt.Sprintf("localhost:%d", port) + mux := http.NewServeMux() + httpS := http.Server{ + Addr: endpoint, + Handler: &handlerSwitcher{ + handler: mux, + }, + } + + healthz.ServeHealthCheck(mux, a.healthCheck) + + rH := handlers.GetRequestHandlers(a.ApplicationServiceClient) + mux.HandleFunc("/app-distribution", rH.GetAppDistribution) + + return &httpS +} + +func (a *EventReporterServer) checkServeErr(name string, err error) { + if err != nil { + if a.stopCh == nil { + // a nil stopCh indicates a graceful shutdown + log.Infof("graceful shutdown %s: %v", name, err) + } else { + log.Fatalf("%s: %v", name, err) + } + } else { + log.Infof("graceful shutdown %s", name) + } +} + +func startListener(host string, port int) (net.Listener, error) { + var conn net.Listener + var realErr error + _ = wait.ExponentialBackoff(backoff, func() (bool, error) { + conn, realErr = net.Listen("tcp", fmt.Sprintf("%s:%d", host, port)) + if realErr != nil { + return false, nil + } + return true, nil + }) + return conn, realErr +} + +func (a *EventReporterServer) Listen() (*Listeners, error) { + mainLn, err := startListener(a.ListenHost, a.ListenPort) + if err != nil { + return nil, err + } + metricsLn, err := startListener(a.MetricsHost, a.MetricsPort) + if err != nil { + io.Close(mainLn) + return nil, err + } + return &Listeners{Main: mainLn, Metrics: metricsLn}, nil +} + +// Run runs the API Server +// We use k8s.io/code-generator/cmd/go-to-protobuf to generate the .proto files from the API types. +// k8s.io/ go-to-protobuf uses protoc-gen-gogo, which comes from gogo/protobuf (a fork of +// golang/protobuf). +func (a *EventReporterServer) Run(ctx context.Context, lns *Listeners) { + httpS := a.newHTTPServer(ctx, a.ListenPort) + tlsConfig := tls.Config{} + tlsConfig.GetCertificate = func(info *tls.ClientHelloInfo) (*tls.Certificate, error) { + return a.settings.Certificate, nil + } + go func() { a.checkServeErr("httpS", httpS.Serve(lns.Main)) }() + go func() { a.checkServeErr("metrics", a.serviceSet.MetricsServer.Serve(lns.Metrics)) }() + go a.RunController(ctx) + + if !cache.WaitForCacheSync(ctx.Done(), a.projInformer.HasSynced, a.appInformer.HasSynced) { + log.Fatal("Timed out waiting for project cache to sync") + } + + a.stopCh = make(chan struct{}) + <-a.stopCh +} + +// NewServer returns a new instance of the Event Reporter server +func NewEventReporterServer(ctx context.Context, opts EventReporterServerOpts) *EventReporterServer { + settingsMgr := settings_util.NewSettingsManager(ctx, opts.KubeClientset, opts.Namespace) + settings, err := settingsMgr.InitializeSettings(true) + errorsutil.CheckError(err) + + appInformerNs := opts.Namespace + if len(opts.ApplicationNamespaces) > 0 { + appInformerNs = "" + } + projFactory := appinformer.NewSharedInformerFactoryWithOptions(opts.AppClientset, 0, appinformer.WithNamespace(opts.Namespace), appinformer.WithTweakListOptions(func(options *metav1.ListOptions) {})) + appFactory := appinformer.NewSharedInformerFactoryWithOptions(opts.AppClientset, 0, appinformer.WithNamespace(appInformerNs), appinformer.WithTweakListOptions(func(options *metav1.ListOptions) {})) + + projInformer := projFactory.Argoproj().V1alpha1().AppProjects().Informer() + projLister := projFactory.Argoproj().V1alpha1().AppProjects().Lister().AppProjects(opts.Namespace) + + appInformer := appFactory.Argoproj().V1alpha1().Applications().Informer() + appLister := appFactory.Argoproj().V1alpha1().Applications().Lister() + + enf := rbac.NewEnforcer(opts.KubeClientset, opts.Namespace, common.ArgoCDRBACConfigMapName, nil) + enf.EnableEnforce(false) + err = enf.SetBuiltinPolicy(assets.BuiltinPolicyCSV) + errorsutil.CheckError(err) + enf.EnableLog(os.Getenv(common.EnvVarRBACDebug) == "1") + + policyEnf := rbacpolicy.NewRBACPolicyEnforcer(enf, projLister) + enf.SetClaimsEnforcerFunc(policyEnf.EnforceClaims) + + dbInstance := db.NewDB(opts.Namespace, settingsMgr, opts.KubeClientset) + + server := &EventReporterServer{ + EventReporterServerOpts: opts, + log: log.NewEntry(log.StandardLogger()), + settings: settings, + settingsMgr: settingsMgr, + enf: enf, + projInformer: projInformer, + projLister: projLister, + appInformer: appInformer, + appLister: appLister, + policyEnforcer: policyEnf, + db: dbInstance, + featureManager: reporter.NewFeatureManager(settingsMgr), + } + + if err != nil { + // Just log. It's not critical. + log.Warnf("Failed to log in-cluster warnings: %v", err) + } + + return server +} + +func newEventReporterServiceSet(a *EventReporterServer) *EventReporterServerSet { + repoService := repository.NewServer(a.RepoClientset, a.db, a.enf, a.Cache, a.appLister, a.projInformer, a.Namespace, a.settingsMgr, false) + metricsServer := metrics.NewMetricsServer(a.MetricsHost, a.MetricsPort) + + return &EventReporterServerSet{ + RepoService: repoService, + MetricsServer: metricsServer, + } +} diff --git a/event_reporter/sharding/sharding.go b/event_reporter/sharding/sharding.go new file mode 100644 index 0000000000000..ae38a4c56cce3 --- /dev/null +++ b/event_reporter/sharding/sharding.go @@ -0,0 +1,104 @@ +package sharding + +import ( + "fmt" + "hash/fnv" + "math" + "os" + "strconv" + "strings" + + argocommon "github.com/argoproj/argo-cd/v2/common" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + + log "github.com/sirupsen/logrus" + + "github.com/argoproj/argo-cd/v2/util/env" +) + +var osHostnameFunction = os.Hostname + +type ( + DistributionFunction func(c *v1alpha1.Application) int + ApplicationFilterFunction func(c *v1alpha1.Application) (bool, int) +) + +type Sharding interface { + GetApplicationFilter(distributionFunction DistributionFunction, shard int) ApplicationFilterFunction + GetDistributionFunction(shardingAlgorithm string) DistributionFunction +} + +type sharding struct{} + +func NewSharding() Sharding { + return &sharding{} +} + +func (s *sharding) GetApplicationFilter(distributionFunction DistributionFunction, shard int) ApplicationFilterFunction { + return func(app *v1alpha1.Application) (bool, int) { + expectedShard := distributionFunction(app) + // TODO: [reporter] provide ability define label with shard number + return expectedShard == shard, expectedShard + } +} + +// GetDistributionFunction returns which DistributionFunction should be used based on the passed algorithm and +// the current datas. +func (s *sharding) GetDistributionFunction(shardingAlgorithm string) DistributionFunction { + log.Infof("Using filter function: %s", shardingAlgorithm) + // TODO: implement switch case for multiple strategies + return s.LegacyDistributionFunction() +} + +func (s *sharding) LegacyDistributionFunction() DistributionFunction { + replicas := env.ParseNumFromEnv(argocommon.EnvEventReporterReplicas, 0, 0, math.MaxInt32) + return func(a *v1alpha1.Application) int { + if replicas == 0 { + return -1 + } + if a == nil { + return 0 + } + id := a.Name + if id == "" { + return 0 + } else { + h := fnv.New32a() + _, _ = h.Write([]byte(id)) + shard := int32(h.Sum32() % uint32(replicas)) + log.Debugf("Application with id=%s will be processed by shard %d", id, shard) + return int(shard) + } + } +} + +// InferShard extracts the shard index based on its hostname. +func InferShard() (int, error) { + hostname, err := osHostnameFunction() + if err != nil { + return 0, err + } + parts := strings.Split(hostname, "-") + if len(parts) == 0 { + return 0, fmt.Errorf("hostname should ends with shard number separated by '-' but got: %s", hostname) + } + shard, err := strconv.Atoi(parts[len(parts)-1]) + if err != nil { + return 0, fmt.Errorf("hostname should ends with shard number separated by '-' but got: %s", hostname) + } + return int(shard), nil +} + +func GetShardNumber() int { + shard := env.ParseNumFromEnv(argocommon.EnvEventReporterShard, -1, -math.MaxInt32, math.MaxInt32) + + if shard < 0 { + var err error + shard, err = InferShard() + if err != nil { + return -1 + } + } + + return shard +} diff --git a/event_reporter/utils/app.go b/event_reporter/utils/app.go new file mode 100644 index 0000000000000..4687b3d36803d --- /dev/null +++ b/event_reporter/utils/app.go @@ -0,0 +1,65 @@ +package utils + +import appv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + +type AppRevisionsFieldNames string + +var ( + AppRevisionFieldName AppRevisionsFieldNames = "Revision" + AppRevisionsFieldName AppRevisionsFieldNames = "Revisions" +) + +type AppUtils struct { + App *appv1.Application +} + +func (au *AppUtils) operationStateSyncExists(fieldToCheck *AppRevisionsFieldNames) bool { + result := au.App != nil && au.App.Status.OperationState != nil && au.App.Status.OperationState.Operation.Sync != nil + if !result { + return false + } + + return revisionsToCheck(RevisionsData{ + Revision: au.App.Status.OperationState.Operation.Sync.Revision, + Revisions: au.App.Status.OperationState.Operation.Sync.Revisions, + }, fieldToCheck) +} + +func (au *AppUtils) operationSyncExists(fieldToCheck *AppRevisionsFieldNames) bool { + result := au.App != nil && au.App.Operation != nil && au.App.Operation.Sync != nil + if !result { + return false + } + + return revisionsToCheck(RevisionsData{ + Revision: au.App.Operation.Sync.Revision, + Revisions: au.App.Operation.Sync.Revisions, + }, fieldToCheck) +} + +func (au *AppUtils) operationSyncResultExists(fieldToCheck *AppRevisionsFieldNames) bool { + result := au.App != nil && au.App.Status.OperationState != nil && au.App.Status.OperationState.SyncResult != nil + if !result { + return false + } + + return revisionsToCheck(RevisionsData{ + Revision: au.App.Status.OperationState.SyncResult.Revision, + Revisions: au.App.Status.OperationState.SyncResult.Revisions, + }, fieldToCheck) +} + +// expected to return true if fieldToCheck == nil +func revisionsToCheck(obj RevisionsData, fieldToCheck *AppRevisionsFieldNames) bool { + if fieldToCheck == nil { + return true + } + if *fieldToCheck == AppRevisionFieldName { + return obj.Revision != "" + } + + if *fieldToCheck == AppRevisionsFieldName { + return len(obj.Revisions) > 0 + } + return true +} diff --git a/event_reporter/utils/app_instance.go b/event_reporter/utils/app_instance.go new file mode 100644 index 0000000000000..18a0c6f46215b --- /dev/null +++ b/event_reporter/utils/app_instance.go @@ -0,0 +1,54 @@ +package utils + +import ( + "strings" + + "github.com/argoproj/gitops-engine/pkg/utils/kube" + + appv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/util/argo" +) + +const appInstanceNameDelimeter = "_" + +type AppIdentity struct { + Name string + Namespace string +} + +// logic connected to /argo-cd/pkg/apis/application/v1alpha1/types.go - InstanceName +func instanceNameIncludesNs(instanceName string) bool { + return strings.Contains(instanceName, appInstanceNameDelimeter) +} + +// logic connected to /argo-cd/pkg/apis/application/v1alpha1/types.go - InstanceName +func parseInstanceName(appNameString string) *AppIdentity { + parts := strings.Split(appNameString, appInstanceNameDelimeter) + namespace := parts[0] + app := parts[1] + + return &AppIdentity{ + Name: app, + Namespace: namespace, + } +} + +func GetParentAppIdentity(a *appv1.Application, appInstanceLabelKey string, installationID string, trackingMethod appv1.TrackingMethod) *AppIdentity { + resourceTracking := argo.NewResourceTracking() + unApp := kube.MustToUnstructured(&a) + + instanceName := resourceTracking.GetAppName(unApp, appInstanceLabelKey, trackingMethod, installationID) + + if instanceNameIncludesNs(instanceName) { + return parseInstanceName(instanceName) + } + + return &AppIdentity{ + Name: instanceName, + Namespace: "", + } +} + +func IsChildApp(parentApp *AppIdentity) bool { + return parentApp.Name != "" +} diff --git a/event_reporter/utils/app_instance_test.go b/event_reporter/utils/app_instance_test.go new file mode 100644 index 0000000000000..c15ea72f939ef --- /dev/null +++ b/event_reporter/utils/app_instance_test.go @@ -0,0 +1,76 @@ +package utils + +import ( + "testing" + + "github.com/stretchr/testify/assert" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + "github.com/argoproj/argo-cd/v2/common" + appsv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/util/argo" +) + +func TestGetParentAppIdentityWithinNonControllerNs(t *testing.T) { + resourceTracking := argo.NewResourceTracking() + annotations := make(map[string]string) + constrollerNs := "runtime" + expectedName := "guestbook" + expectedNamespace := "test-apps" + + guestbookApp := appsv1.Application{ + TypeMeta: metav1.TypeMeta{ + Kind: "Application", + APIVersion: "argoproj.io/v1alpha1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: expectedName, + Namespace: expectedNamespace, + }, + } + annotations[common.AnnotationKeyAppInstance] = resourceTracking.BuildAppInstanceValue(argo.AppInstanceValue{ + Name: "test", + ApplicationName: guestbookApp.InstanceName(constrollerNs), + Group: "group", + Kind: "Rollout", + Namespace: "test-resources", + }) + guestbookApp.Annotations = annotations + + res := GetParentAppIdentity(&guestbookApp, common.LabelKeyAppInstance, "", "annotation") + + assert.Equal(t, expectedName, res.Name) + assert.Equal(t, expectedNamespace, res.Namespace) +} + +func TestGetParentAppIdentityWithinControllerNs(t *testing.T) { + resourceTracking := argo.NewResourceTracking() + annotations := make(map[string]string) + constrollerNs := "runtime" + expectedName := "guestbook" + expectedNamespace := "" + + guestbookApp := appsv1.Application{ + TypeMeta: metav1.TypeMeta{ + Kind: "Application", + APIVersion: "argoproj.io/v1alpha1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: expectedName, + Namespace: constrollerNs, + }, + } + annotations[common.AnnotationKeyAppInstance] = resourceTracking.BuildAppInstanceValue(argo.AppInstanceValue{ + Name: "test", + ApplicationName: guestbookApp.InstanceName(constrollerNs), + Group: "group", + Kind: "Rollout", + Namespace: "test-resources", + }) + guestbookApp.Annotations = annotations + + res := GetParentAppIdentity(&guestbookApp, common.LabelKeyAppInstance, "", "annotation") + + assert.Equal(t, expectedName, res.Name) + assert.Equal(t, expectedNamespace, res.Namespace) +} diff --git a/event_reporter/utils/app_revision.go b/event_reporter/utils/app_revision.go new file mode 100644 index 0000000000000..a82ab41e3443b --- /dev/null +++ b/event_reporter/utils/app_revision.go @@ -0,0 +1,250 @@ +package utils + +import ( + "encoding/json" + + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + + appv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" +) + +type AppSyncRevisionsMetadata struct { + SyncRevisions []*RevisionWithMetadata `json:"syncRevisions" protobuf:"bytes,1,name=syncRevisions"` + ChangeRevisions []*RevisionWithMetadata `json:"changeRevisions" protobuf:"bytes,2,name=changeRevisions"` +} + +type RevisionWithMetadata struct { + Revision string `json:"revision" protobuf:"bytes,1,name=revision"` + Metadata *appv1.RevisionMetadata `json:"metadata,omitempty" protobuf:"bytes,2,name=metadata"` +} + +type RevisionsData struct { + Revision string `json:"revision,omitempty" protobuf:"bytes,1,opt,name=revision"` + Revisions []string `json:"revisions,omitempty" protobuf:"bytes,2,opt,name=revisions"` +} + +const annotationRevisionKey = "app.meta.revisions-metadata" + +func (asrm *AppSyncRevisionsMetadata) GetSyncRevisionAt(idx int) *RevisionWithMetadata { + if asrm == nil || asrm.SyncRevisions == nil || idx < 0 || idx >= len(asrm.SyncRevisions) { + return nil + } + return asrm.SyncRevisions[idx] +} + +func GetLatestAppHistoryId(a *appv1.Application) int64 { + if lastHistory := getLatestAppHistoryItem(a); lastHistory != nil { + return lastHistory.ID + } + + return 0 +} + +func getLatestAppHistoryItem(a *appv1.Application) *appv1.RevisionHistory { + if len(a.Status.History) > 0 { + return &a.Status.History[len(a.Status.History)-1] + } + + return nil +} + +func GetApplicationLatestRevision(a *appv1.Application) string { + if lastHistory := getLatestAppHistoryItem(a); lastHistory != nil { + return lastHistory.Revision + } + + return a.Status.Sync.Revision +} + +func GetApplicationLatestRevisions(a *appv1.Application) []string { + if lastHistory := getLatestAppHistoryItem(a); lastHistory != nil { + return lastHistory.Revisions + } + + return a.Status.Sync.Revisions +} + +func GetOperationRevision(a *appv1.Application) string { + if a == nil { + return "" + } + au := &AppUtils{App: a} + // this value will be used in case if application hasn't resources , like gitsource + revision := a.Status.Sync.Revision + if au.operationStateSyncExists(&AppRevisionFieldName) { + revision = a.Status.OperationState.Operation.Sync.Revision + } else if au.operationSyncExists(&AppRevisionFieldName) { + revision = a.Operation.Sync.Revision + } + + return revision +} + +func GetOperationRevisions(a *appv1.Application) []string { + if a == nil { + return nil + } + au := &AppUtils{App: a} + + // this value will be used in case if application hasn't resources , like gitsource + revisions := a.Status.Sync.Revisions + if au.operationStateSyncExists(&AppRevisionsFieldName) { + revisions = a.Status.OperationState.Operation.Sync.Revisions + } else if au.operationSyncExists(&AppRevisionsFieldName) { + revisions = a.Operation.Sync.Revisions + } + + return revisions +} + +func GetOperationSyncResultRevision(a *appv1.Application) *string { + au := &AppUtils{App: a} + if au.operationSyncResultExists(nil) { + return &a.Status.OperationState.SyncResult.Revision + } + + return nil +} + +func GetOperationSyncResultRevisions(a *appv1.Application) *[]string { + au := &AppUtils{App: a} + if au.operationSyncResultExists(nil) { + return &a.Status.OperationState.SyncResult.Revisions + } + + return nil +} + +func GetOperationSyncRevisions(a *appv1.Application) []string { + if a == nil { + return []string{} + } + au := &AppUtils{App: a} + + // this value will be used in case if application hasn't resources, like empty gitsource + revisions := getRevisions(RevisionsData{ + Revision: a.Status.Sync.Revision, + Revisions: a.Status.Sync.Revisions, + }) + + if au.operationStateSyncExists(nil) { + revisions = getRevisions(RevisionsData{ + Revision: a.Status.OperationState.Operation.Sync.Revision, + Revisions: a.Status.OperationState.Operation.Sync.Revisions, + }) + } else if au.operationSyncExists(nil) { + revisions = getRevisions(RevisionsData{ + Revision: a.Operation.Sync.Revision, + Revisions: a.Operation.Sync.Revisions, + }) + } + + return revisions +} + +// for monorepo support: list with revisions where actual changes to source directory were committed +func GetOperationChangeRevisions(a *appv1.Application) []string { + var revisions []string + + if a == nil { + return revisions + } + au := &AppUtils{App: a} + + // this value will be used in case if application hasn't resources, like empty gitsource + if au.operationStateSyncExists(nil) { + if a.Status.OperationState.Operation.Sync.ChangeRevision != "" || a.Status.OperationState.Operation.Sync.ChangeRevisions != nil { + revisions = getRevisions(RevisionsData{ + Revision: a.Status.OperationState.Operation.Sync.ChangeRevision, + Revisions: a.Status.OperationState.Operation.Sync.ChangeRevisions, + }) + } + } else if au.operationSyncExists(nil) { + if a.Operation.Sync.ChangeRevision != "" || a.Operation.Sync.ChangeRevisions != nil { + revisions = getRevisions(RevisionsData{ + Revision: a.Operation.Sync.ChangeRevision, + Revisions: a.Operation.Sync.ChangeRevisions, + }) + } + } + + return revisions +} + +func getRevisions(rd RevisionsData) []string { + if rd.Revisions != nil { + return rd.Revisions + } + + return []string{rd.Revision} +} + +func AddCommitsDetailsToAnnotations(unstrApp *unstructured.Unstructured, revisionsMetadata *AppSyncRevisionsMetadata) *unstructured.Unstructured { + if revisionsMetadata == nil || unstrApp == nil { + return unstrApp + } + + if field, _, _ := unstructured.NestedFieldCopy(unstrApp.Object, "metadata", "annotations"); field == nil { + _ = unstructured.SetNestedStringMap(unstrApp.Object, map[string]string{}, "metadata", "annotations") + } + + jsonRevisionsMetadata, err := json.Marshal(revisionsMetadata) + if err != nil { + return unstrApp + } + + _ = unstructured.SetNestedField(unstrApp.Object, string(jsonRevisionsMetadata), "metadata", "annotations", annotationRevisionKey) + + return unstrApp +} + +func AddCommitsDetailsToAppAnnotations(app appv1.Application, revisionsMetadata *AppSyncRevisionsMetadata) appv1.Application { + if revisionsMetadata == nil { + return app + } + + if app.ObjectMeta.Annotations == nil { + app.ObjectMeta.Annotations = map[string]string{} + } + + jsonRevisionsMetadata, err := json.Marshal(revisionsMetadata) + if err != nil { + return app + } + + app.ObjectMeta.Annotations[annotationRevisionKey] = string(jsonRevisionsMetadata) + + return app +} + +func AddCommitDetailsToLabels(u *unstructured.Unstructured, revisionMetadata *appv1.RevisionMetadata) *unstructured.Unstructured { + if revisionMetadata == nil || u == nil { + return u + } + + if field, _, _ := unstructured.NestedFieldCopy(u.Object, "metadata", "labels"); field == nil { + _ = unstructured.SetNestedStringMap(u.Object, map[string]string{}, "metadata", "labels") + } + + _ = unstructured.SetNestedField(u.Object, revisionMetadata.Date.Format("2006-01-02T15:04:05.000Z"), "metadata", "labels", "app.meta.commit-date") + _ = unstructured.SetNestedField(u.Object, revisionMetadata.Author, "metadata", "labels", "app.meta.commit-author") + _ = unstructured.SetNestedField(u.Object, revisionMetadata.Message, "metadata", "labels", "app.meta.commit-message") + + return u +} + +func AddCommitsDetailsToAppLabels(app *appv1.Application, revisionMetadata *appv1.RevisionMetadata) *appv1.Application { + if revisionMetadata == nil { + return app + } + + if app.ObjectMeta.Labels == nil { + app.ObjectMeta.Labels = map[string]string{} + } + + app.ObjectMeta.Labels["app.meta.commit-date"] = revisionMetadata.Date.Format("2006-01-02T15:04:05.000Z") + app.ObjectMeta.Labels["app.meta.commit-author"] = revisionMetadata.Author + app.ObjectMeta.Labels["app.meta.commit-message"] = revisionMetadata.Message + + return app +} diff --git a/event_reporter/utils/app_revision_test.go b/event_reporter/utils/app_revision_test.go new file mode 100644 index 0000000000000..88cb9bccd8c82 --- /dev/null +++ b/event_reporter/utils/app_revision_test.go @@ -0,0 +1,664 @@ +package utils + +import ( + "testing" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + + "github.com/stretchr/testify/assert" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "sigs.k8s.io/yaml" +) + +func TestGetLatestAppHistoryId(t *testing.T) { + history1Id := int64(1) + history2Id := int64(2) + + t.Run("resource revision should be 0", func(t *testing.T) { + noStatusHistoryAppMock := v1alpha1.Application{} + + idResult := GetLatestAppHistoryId(&noStatusHistoryAppMock) + assert.Equal(t, int64(0), idResult) + + emptyStatusHistoryAppMock := v1alpha1.Application{ + Status: v1alpha1.ApplicationStatus{ + History: []v1alpha1.RevisionHistory{}, + }, + } + + id2Result := GetLatestAppHistoryId(&emptyStatusHistoryAppMock) + assert.Equal(t, int64(0), id2Result) + }) + + t.Run("resource revision should be taken from latest history.Id", func(t *testing.T) { + appMock := v1alpha1.Application{ + Status: v1alpha1.ApplicationStatus{ + History: []v1alpha1.RevisionHistory{ + { + ID: history1Id, + }, + { + ID: history2Id, + }, + }, + }, + } + + revisionResult := GetLatestAppHistoryId(&appMock) + assert.Equal(t, revisionResult, history2Id) + }) +} + +func TestGetApplicationLatestRevision(t *testing.T) { + appRevision := "a-revision" + history1Revision := "history-revision-1" + history2Revision := "history-revision-2" + + t.Run("resource revision should be taken from sync.revision", func(t *testing.T) { + noStatusHistoryAppMock := v1alpha1.Application{ + Status: v1alpha1.ApplicationStatus{ + Sync: v1alpha1.SyncStatus{ + Revision: appRevision, + }, + }, + } + + revisionResult := GetApplicationLatestRevision(&noStatusHistoryAppMock) + assert.Equal(t, revisionResult, appRevision) + + emptyStatusHistoryAppMock := v1alpha1.Application{ + Status: v1alpha1.ApplicationStatus{ + Sync: v1alpha1.SyncStatus{ + Revision: appRevision, + }, + History: []v1alpha1.RevisionHistory{}, + }, + } + + revision2Result := GetApplicationLatestRevision(&emptyStatusHistoryAppMock) + assert.Equal(t, revision2Result, appRevision) + }) + + t.Run("resource revision should be taken from latest history.revision", func(t *testing.T) { + appMock := v1alpha1.Application{ + Status: v1alpha1.ApplicationStatus{ + Sync: v1alpha1.SyncStatus{ + Revision: appRevision, + }, + History: []v1alpha1.RevisionHistory{ + { + Revision: history1Revision, + }, + { + Revision: history2Revision, + }, + }, + }, + } + + revisionResult := GetApplicationLatestRevision(&appMock) + assert.Equal(t, revisionResult, history2Revision) + }) +} + +func yamlToUnstructured(jsonStr string) *unstructured.Unstructured { + obj := make(map[string]interface{}) + err := yaml.Unmarshal([]byte(jsonStr), &obj) + if err != nil { + panic(err) + } + return &unstructured.Unstructured{Object: obj} +} + +func jsonToAppSyncRevision(jsonStr string) *AppSyncRevisionsMetadata { + var obj AppSyncRevisionsMetadata + err := yaml.Unmarshal([]byte(jsonStr), &obj) + if err != nil { + panic(err) + } + return &obj +} + +func TestAddCommitsDetailsToAnnotations(t *testing.T) { + revisionMetadata := AppSyncRevisionsMetadata{ + SyncRevisions: []*RevisionWithMetadata{{ + Metadata: &v1alpha1.RevisionMetadata{ + Author: "demo usert", + Date: metav1.Time{}, + Message: "some message", + }, + }}, + } + + t.Run("set annotation when annotations object missing", func(t *testing.T) { + resource := yamlToUnstructured(` + apiVersion: v1 + kind: Service + metadata: + name: helm-guestbook + namespace: default + resourceVersion: "123" + uid: "4" + spec: + selector: + app: guestbook + type: LoadBalancer + status: + loadBalancer: + ingress: + - hostname: localhost`, + ) + + result := AddCommitsDetailsToAnnotations(resource, &revisionMetadata) + + revMetadatUnstructured := jsonToAppSyncRevision(result.GetAnnotations()[annotationRevisionKey]) + + assert.Equal(t, revisionMetadata.SyncRevisions[0].Metadata.Author, revMetadatUnstructured.SyncRevisions[0].Metadata.Author) + assert.Equal(t, revisionMetadata.SyncRevisions[0].Metadata.Message, revMetadatUnstructured.SyncRevisions[0].Metadata.Message) + }) + + t.Run("set annotation when annotations present", func(t *testing.T) { + resource := yamlToUnstructured(` + apiVersion: v1 + kind: Service + metadata: + name: helm-guestbook + namespace: default + annotations: + link: http://my-grafana.com/pre-generated-link + spec: + selector: + app: guestbook + type: LoadBalancer + status: + loadBalancer: + ingress: + - hostname: localhost`, + ) + + result := AddCommitsDetailsToAnnotations(resource, &revisionMetadata) + + revMetadatUnstructured := jsonToAppSyncRevision(result.GetAnnotations()[annotationRevisionKey]) + + assert.Equal(t, revisionMetadata.SyncRevisions[0].Metadata.Author, revMetadatUnstructured.SyncRevisions[0].Metadata.Author) + assert.Equal(t, revisionMetadata.SyncRevisions[0].Metadata.Message, revMetadatUnstructured.SyncRevisions[0].Metadata.Message) + }) +} + +func TestAddCommitsDetailsToAppAnnotations(t *testing.T) { + revisionMetadata := AppSyncRevisionsMetadata{ + SyncRevisions: []*RevisionWithMetadata{{ + Metadata: &v1alpha1.RevisionMetadata{ + Author: "demo usert", + Date: metav1.Time{}, + Message: "some message", + }, + }}, + } + + t.Run("set annotation when annotations object missing", func(t *testing.T) { + resource := v1alpha1.Application{ + ObjectMeta: metav1.ObjectMeta{}, + } + + result := AddCommitsDetailsToAppAnnotations(resource, &revisionMetadata) + + revMetadatUnstructured := jsonToAppSyncRevision(result.GetAnnotations()[annotationRevisionKey]) + + assert.Equal(t, revisionMetadata.SyncRevisions[0].Metadata.Author, revMetadatUnstructured.SyncRevisions[0].Metadata.Author) + assert.Equal(t, revisionMetadata.SyncRevisions[0].Metadata.Message, revMetadatUnstructured.SyncRevisions[0].Metadata.Message) + }) + + t.Run("set annotation when annotations present", func(t *testing.T) { + resource := v1alpha1.Application{ + ObjectMeta: metav1.ObjectMeta{ + Annotations: map[string]string{ + "test": "value", + }, + }, + } + + result := AddCommitsDetailsToAppAnnotations(resource, &revisionMetadata) + + revMetadatUnstructured := jsonToAppSyncRevision(result.GetAnnotations()[annotationRevisionKey]) + + assert.Equal(t, revisionMetadata.SyncRevisions[0].Metadata.Author, revMetadatUnstructured.SyncRevisions[0].Metadata.Author) + assert.Equal(t, revisionMetadata.SyncRevisions[0].Metadata.Message, revMetadatUnstructured.SyncRevisions[0].Metadata.Message) + }) +} + +func TestGetRevisions(t *testing.T) { + t.Run("should return revisions when only they passed", func(t *testing.T) { + val := "test" + result := getRevisions(RevisionsData{ + Revisions: []string{val}, + }) + assert.Len(t, result, 1) + assert.Equal(t, val, result[0]) + }) + t.Run("should return revisions when revision also passed", func(t *testing.T) { + val := "test" + result := getRevisions(RevisionsData{ + Revisions: []string{val, "test2"}, + Revision: "fail", + }) + assert.Len(t, result, 2) + assert.Equal(t, val, result[0]) + }) + t.Run("should return revision", func(t *testing.T) { + val := "test" + result := getRevisions(RevisionsData{ + Revision: val, + }) + assert.Len(t, result, 1) + assert.Equal(t, val, result[0]) + }) +} + +func TestGetOperationSyncRevisions(t *testing.T) { + t.Run("should return Status.Sync.Revision like for new apps", func(t *testing.T) { + expectedResult := "test" + app := v1alpha1.Application{ + Status: v1alpha1.ApplicationStatus{ + Sync: v1alpha1.SyncStatus{ + Revision: expectedResult, + }, + }, + } + result := GetOperationSyncRevisions(&app) + + assert.Len(t, result, 1) + assert.Equal(t, expectedResult, result[0]) + }) + + t.Run("should return Status.Sync.Revisions like for new apps", func(t *testing.T) { + expectedResult := "multi-1" + app := v1alpha1.Application{ + Status: v1alpha1.ApplicationStatus{ + Sync: v1alpha1.SyncStatus{ + Revisions: []string{expectedResult, "multi-2"}, + Revision: "single", + }, + }, + } + + result := GetOperationSyncRevisions(&app) + + assert.Len(t, result, 2) + assert.Equal(t, expectedResult, result[0]) + }) + + t.Run("should return a.Status.OperationState.Operation.Sync.Revision", func(t *testing.T) { + expectedResult := "multi-1" + app := v1alpha1.Application{ + Status: v1alpha1.ApplicationStatus{ + Sync: v1alpha1.SyncStatus{ + Revision: "fallack", + }, + OperationState: &v1alpha1.OperationState{ + Operation: v1alpha1.Operation{ + Sync: &v1alpha1.SyncOperation{ + Revision: expectedResult, + }, + }, + }, + }, + } + + result := GetOperationSyncRevisions(&app) + + assert.Len(t, result, 1) + assert.Equal(t, expectedResult, result[0]) + }) + + t.Run("should return a.Status.OperationState.Operation.Sync.Revisions", func(t *testing.T) { + expectedResult := "multi-1" + + app := v1alpha1.Application{ + Status: v1alpha1.ApplicationStatus{ + Sync: v1alpha1.SyncStatus{ + Revision: "fallack", + }, + OperationState: &v1alpha1.OperationState{ + Operation: v1alpha1.Operation{ + Sync: &v1alpha1.SyncOperation{ + Revisions: []string{expectedResult, "multi-2"}, + Revision: "single", + }, + }, + }, + }, + } + + result := GetOperationSyncRevisions(&app) + + assert.Len(t, result, 2) + assert.Equal(t, expectedResult, result[0]) + }) + + t.Run("should return a.Operation.Sync.Revision for first app sync", func(t *testing.T) { + expectedResult := "multi-1" + app := v1alpha1.Application{ + Status: v1alpha1.ApplicationStatus{ + Sync: v1alpha1.SyncStatus{ + Revision: "fallack", + }, + }, + Operation: &v1alpha1.Operation{ + Sync: &v1alpha1.SyncOperation{ + Revision: expectedResult, + }, + }, + } + + result := GetOperationSyncRevisions(&app) + + assert.Len(t, result, 1) + assert.Equal(t, expectedResult, result[0]) + }) + + t.Run("should return a.Operation.Sync.Revisions for first app sync", func(t *testing.T) { + expectedResult := "multi-1" + + app := v1alpha1.Application{ + Status: v1alpha1.ApplicationStatus{ + Sync: v1alpha1.SyncStatus{ + Revision: "fallack", + }, + }, + Operation: &v1alpha1.Operation{ + Sync: &v1alpha1.SyncOperation{ + Revisions: []string{expectedResult, "multi-2"}, + Revision: "single", + }, + }, + } + + result := GetOperationSyncRevisions(&app) + + assert.Len(t, result, 2) + assert.Equal(t, expectedResult, result[0]) + }) +} + +func TestAddCommitDetailsToLabels(t *testing.T) { + revisionMetadata := v1alpha1.RevisionMetadata{ + Author: "demo usert", + Date: metav1.Time{}, + Message: "some message", + } + + t.Run("set labels when lable object missing", func(t *testing.T) { + resource := yamlToUnstructured(` + apiVersion: v1 + kind: Service + metadata: + name: helm-guestbook + namespace: default + resourceVersion: "123" + uid: "4" + spec: + selector: + app: guestbook + type: LoadBalancer + status: + loadBalancer: + ingress: + - hostname: localhost`, + ) + + result := AddCommitDetailsToLabels(resource, &revisionMetadata) + labels := result.GetLabels() + assert.Equal(t, revisionMetadata.Author, labels["app.meta.commit-author"]) + assert.Equal(t, revisionMetadata.Message, labels["app.meta.commit-message"]) + }) + + t.Run("set labels when labels present", func(t *testing.T) { + resource := yamlToUnstructured(` + apiVersion: v1 + kind: Service + metadata: + name: helm-guestbook + namespace: default + labels: + link: http://my-grafana.com/pre-generated-link + spec: + selector: + app: guestbook + type: LoadBalancer + status: + loadBalancer: + ingress: + - hostname: localhost`, + ) + + result := AddCommitDetailsToLabels(resource, &revisionMetadata) + labels := result.GetLabels() + assert.Equal(t, revisionMetadata.Author, labels["app.meta.commit-author"]) + assert.Equal(t, revisionMetadata.Message, labels["app.meta.commit-message"]) + assert.Equal(t, "http://my-grafana.com/pre-generated-link", result.GetLabels()["link"]) + }) +} + +func TestGetSyncRevisionAt(t *testing.T) { + t.Run("should return nil once idx out of range", func(t *testing.T) { + revisionMetadata := AppSyncRevisionsMetadata{ + SyncRevisions: []*RevisionWithMetadata{{ + Metadata: &v1alpha1.RevisionMetadata{ + Author: "demo usert", + Date: metav1.Time{}, + Message: "some message", + }, + }}, + } + + assert.Nil(t, revisionMetadata.GetSyncRevisionAt(-1)) + assert.Nil(t, revisionMetadata.GetSyncRevisionAt(1)) + }) + t.Run("should return nil if data missing", func(t *testing.T) { + revisionMetadata := AppSyncRevisionsMetadata{} + + assert.Nil(t, revisionMetadata.GetSyncRevisionAt(1)) + }) + t.Run("should return correct idx", func(t *testing.T) { + revisionMetadata := AppSyncRevisionsMetadata{ + SyncRevisions: []*RevisionWithMetadata{ + { + Metadata: &v1alpha1.RevisionMetadata{ + Author: "demo usert", + Date: metav1.Time{}, + Message: "some message", + }, + }, + { + Metadata: &v1alpha1.RevisionMetadata{ + Author: "demo user2", + Date: metav1.Time{}, + Message: "some message 2", + }, + }, + }, + } + + syncRev := revisionMetadata.GetSyncRevisionAt(1) + assert.NotNil(t, syncRev) + assert.Equal(t, "demo user2", syncRev.Metadata.Author) + assert.Equal(t, "some message 2", syncRev.Metadata.Message) + }) +} + +func TestGetOperationRevision(t *testing.T) { + t.Run("should return empty strint once app in nil", func(t *testing.T) { + assert.Equal(t, "", GetOperationRevision(nil)) + }) + t.Run("should return Status.Sync.Revision as fallback", func(t *testing.T) { + assert.Equal(t, "Status.Sync.Revision", GetOperationRevision(&v1alpha1.Application{ + Status: v1alpha1.ApplicationStatus{ + Sync: v1alpha1.SyncStatus{ + Revision: "Status.Sync.Revision", + }, + }, + })) + }) + t.Run("should return Status.OperationState.Operation.Sync.Revision", func(t *testing.T) { + assert.Equal(t, "Status.OperationState.Operation.Sync.Revision", GetOperationRevision(&v1alpha1.Application{ + Status: v1alpha1.ApplicationStatus{ + Sync: v1alpha1.SyncStatus{ + Revision: "Status.Sync.Revision", + }, + OperationState: &v1alpha1.OperationState{ + Operation: v1alpha1.Operation{ + Sync: &v1alpha1.SyncOperation{ + Revision: "Status.OperationState.Operation.Sync.Revision", + }, + }, + }, + }, + Operation: &v1alpha1.Operation{ + Sync: &v1alpha1.SyncOperation{ + Revision: "Operation.Sync.Revision", + }, + }, + })) + }) + t.Run("should return Status-Sync-Revision", func(t *testing.T) { + assert.Equal(t, "Operation.Sync.Revision", GetOperationRevision(&v1alpha1.Application{ + Status: v1alpha1.ApplicationStatus{ + Sync: v1alpha1.SyncStatus{ + Revision: "Status-Sync-Revision", + }, + }, + Operation: &v1alpha1.Operation{ + Sync: &v1alpha1.SyncOperation{ + Revision: "Operation.Sync.Revision", + }, + }, + })) + }) +} + +func TestGetOperationRevisions(t *testing.T) { + t.Run("should return empty strint once app in nil", func(t *testing.T) { + assert.Nil(t, GetOperationRevisions(nil)) + }) + t.Run("should return Status.Sync.Revisions as fallback", func(t *testing.T) { + res := GetOperationRevisions(&v1alpha1.Application{ + Status: v1alpha1.ApplicationStatus{ + Sync: v1alpha1.SyncStatus{ + Revision: "Status.Sync.Revision", + Revisions: []string{"Status.Sync.Revisions"}, + }, + }, + }) + assert.Len(t, res, 1) + assert.Equal(t, "Status.Sync.Revisions", res[0]) + }) + t.Run("should return Status.OperationState.Operation.Sync.Revisions", func(t *testing.T) { + res := GetOperationRevisions(&v1alpha1.Application{ + Status: v1alpha1.ApplicationStatus{ + Sync: v1alpha1.SyncStatus{ + Revision: "Status.Sync.Revision", + Revisions: []string{"Status.Sync.Revisions"}, + }, + OperationState: &v1alpha1.OperationState{ + Operation: v1alpha1.Operation{ + Sync: &v1alpha1.SyncOperation{ + Revision: "Status.OperationState.Operation.Sync.Revision", + Revisions: []string{"Status.OperationState.Operation.Sync.Revisions"}, + }, + }, + }, + }, + Operation: &v1alpha1.Operation{ + Sync: &v1alpha1.SyncOperation{ + Revision: "Operation.Sync.Revision", + Revisions: []string{"Operation.Sync.Revisions"}, + }, + }, + }) + assert.Len(t, res, 1) + assert.Equal(t, "Status.OperationState.Operation.Sync.Revisions", res[0]) + }) + t.Run("should return Status-Sync-Revisions", func(t *testing.T) { + res := GetOperationRevisions(&v1alpha1.Application{ + Status: v1alpha1.ApplicationStatus{ + Sync: v1alpha1.SyncStatus{ + Revision: "Status-Sync-Revision", + }, + }, + Operation: &v1alpha1.Operation{ + Sync: &v1alpha1.SyncOperation{ + Revision: "Operation.Sync.Revision", + Revisions: []string{"Operation.Sync.Revisions"}, + }, + }, + }) + assert.Len(t, res, 1) + assert.Equal(t, "Operation.Sync.Revisions", res[0]) + }) +} + +func TestGetOperationSyncResultRevision(t *testing.T) { + t.Run("should return nil", func(t *testing.T) { + assert.Nil(t, GetOperationSyncResultRevision(nil)) + assert.Nil(t, GetOperationSyncResultRevision(&v1alpha1.Application{ + Status: v1alpha1.ApplicationStatus{ + OperationState: &v1alpha1.OperationState{ + Operation: v1alpha1.Operation{ + Sync: &v1alpha1.SyncOperation{ + Revision: "Status.OperationState.Operation.Sync.Revision", + Revisions: []string{"Status.OperationState.Operation.Sync.Revisions"}, + }, + }, + }, + }, + })) + }) + t.Run("should return revision", func(t *testing.T) { + res := GetOperationSyncResultRevision(&v1alpha1.Application{ + Status: v1alpha1.ApplicationStatus{ + OperationState: &v1alpha1.OperationState{ + SyncResult: &v1alpha1.SyncOperationResult{ + Revision: "Status.OperationState.SyncResult.Revision", + Revisions: []string{"Status.OperationState.SyncResult.Revisions"}, + }, + }, + }, + }) + assert.Equal(t, "Status.OperationState.SyncResult.Revision", *res) + }) +} + +func TestGetOperationSyncResultRevisions(t *testing.T) { + t.Run("should return nil", func(t *testing.T) { + assert.Nil(t, GetOperationSyncResultRevisions(nil)) + assert.Nil(t, GetOperationSyncResultRevisions(&v1alpha1.Application{ + Status: v1alpha1.ApplicationStatus{ + OperationState: &v1alpha1.OperationState{ + Operation: v1alpha1.Operation{ + Sync: &v1alpha1.SyncOperation{ + Revision: "Status.OperationState.Operation.Sync.Revision", + Revisions: []string{"Status.OperationState.Operation.Sync.Revisions"}, + }, + }, + }, + }, + })) + }) + t.Run("should return revisions", func(t *testing.T) { + res := GetOperationSyncResultRevisions(&v1alpha1.Application{ + Status: v1alpha1.ApplicationStatus{ + OperationState: &v1alpha1.OperationState{ + SyncResult: &v1alpha1.SyncOperationResult{ + Revision: "Status.OperationState.SyncResult.Revision", + Revisions: []string{"Status.OperationState.SyncResult.Revisions"}, + }, + }, + }, + }) + assert.NotNil(t, res) + assert.Len(t, *res, 1) + }) +} diff --git a/event_reporter/utils/app_version.go b/event_reporter/utils/app_version.go new file mode 100644 index 0000000000000..fc6b0d186d6aa --- /dev/null +++ b/event_reporter/utils/app_version.go @@ -0,0 +1,35 @@ +package utils + +import ( + "encoding/json" + + log "github.com/sirupsen/logrus" + + "github.com/argoproj/argo-cd/v2/pkg/apiclient/events" + "github.com/argoproj/argo-cd/v2/pkg/sources_server_client" + "github.com/argoproj/argo-cd/v2/reposerver/apiclient" +) + +func RepoAppVersionsToEvent(applicationVersions *apiclient.ApplicationVersions) (*events.ApplicationVersions, error) { + applicationVersionsEvents := &events.ApplicationVersions{} + applicationVersionsData, _ := json.Marshal(applicationVersions) + err := json.Unmarshal(applicationVersionsData, applicationVersionsEvents) + if err != nil { + return nil, err + } + return applicationVersionsEvents, nil +} + +func SourcesAppVersionsToRepo(applicationVersions *sources_server_client.AppVersionResult, logCtx *log.Entry) *apiclient.ApplicationVersions { + if applicationVersions == nil { + return nil + } + applicationVersionsRepo := &apiclient.ApplicationVersions{} + applicationVersionsData, _ := json.Marshal(applicationVersions) + err := json.Unmarshal(applicationVersionsData, applicationVersionsRepo) + if err != nil { + logCtx.Errorf("can't unmarshal app version: %v", err) + return nil + } + return applicationVersionsRepo +} diff --git a/event_reporter/utils/utils.go b/event_reporter/utils/utils.go new file mode 100644 index 0000000000000..8857f7d39150c --- /dev/null +++ b/event_reporter/utils/utils.go @@ -0,0 +1,80 @@ +package utils + +import ( + "fmt" + + "github.com/argoproj/gitops-engine/pkg/health" + log "github.com/sirupsen/logrus" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + + appv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" +) + +func SetHealthStatusIfMissing(rs *appv1.ResourceStatus) { + if rs.Health == nil && rs.Status == appv1.SyncStatusCodeSynced { + // for resources without health status we need to add 'Healthy' status + // when they are synced because we might have sent an event with 'Missing' + // status earlier and they would be stuck in it if we don't switch to 'Healthy' + rs.Health = &appv1.HealthStatus{ + Status: health.HealthStatusHealthy, + } + } +} + +func IsApp(rs appv1.ResourceStatus) bool { + return rs.GroupVersionKind().String() == appv1.ApplicationSchemaGroupVersionKind.String() +} + +func LogWithAppStatus(a *appv1.Application, logCtx *log.Entry, ts string) *log.Entry { + return logCtx.WithFields(log.Fields{ + "sync": a.Status.Sync.Status, + "health": a.Status.Health.Status, + "resourceVersion": a.ResourceVersion, + "ts": ts, + }) +} + +func LogWithResourceStatus(logCtx *log.Entry, rs appv1.ResourceStatus) *log.Entry { + logCtx = logCtx.WithField("sync", rs.Status) + if rs.Health != nil { + logCtx = logCtx.WithField("health", rs.Health.Status) + } + + return logCtx +} + +func SafeString(s *string) string { + if s == nil { + return "" + } + return *s +} + +func GetAppAsResource(a *appv1.Application) *appv1.ResourceStatus { + return &appv1.ResourceStatus{ + Name: a.Name, + Namespace: a.Namespace, + Version: "v1alpha1", + Kind: "Application", + Group: "argoproj.io", + Status: a.Status.Sync.Status, + Health: &a.Status.Health, + RequiresPruning: a.DeletionTimestamp != nil, + } +} + +func AddDestNamespaceToManifest(resourceManifest []byte, rs *appv1.ResourceStatus) (*unstructured.Unstructured, error) { + u, err := appv1.UnmarshalToUnstructured(string(resourceManifest)) + if err != nil { + return nil, fmt.Errorf("failed to unmarshal manifest: %w", err) + } + + if u.GetNamespace() == rs.Namespace { + return u, nil + } + + // need to change namespace + u.SetNamespace(rs.Namespace) + + return u, nil +} diff --git a/event_reporter/utils/utils_test.go b/event_reporter/utils/utils_test.go new file mode 100644 index 0000000000000..7dca3ea6a9e4d --- /dev/null +++ b/event_reporter/utils/utils_test.go @@ -0,0 +1,16 @@ +package utils + +import ( + "testing" + + appsv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + + "github.com/argoproj/gitops-engine/pkg/health" + "github.com/stretchr/testify/assert" +) + +func TestSetHealthStatusIfMissing(t *testing.T) { + resource := appsv1.ResourceStatus{Status: appsv1.SyncStatusCodeSynced} + SetHealthStatusIfMissing(&resource) + assert.Equal(t, health.HealthStatusHealthy, resource.Health.Status) +} diff --git a/go.mod b/go.mod index e50976b450568..dfd2b0f213425 100644 --- a/go.mod +++ b/go.mod @@ -7,6 +7,7 @@ require ( github.com/Azure/kubelogin v0.1.6 github.com/Masterminds/semver/v3 v3.3.1 github.com/Masterminds/sprig/v3 v3.3.0 + github.com/PaesslerAG/jsonpath v0.1.1 github.com/TomOnTime/utfutil v0.0.0-20180511104225-09c41003ee1d github.com/alicebob/miniredis/v2 v2.33.0 github.com/antonmedv/expr v1.15.1 @@ -14,6 +15,7 @@ require ( github.com/argoproj/notifications-engine v0.4.1-0.20241007194503-2fef5c9049fd github.com/argoproj/pkg v0.13.7-0.20230626144333-d56162821bd1 github.com/aws/aws-sdk-go v1.55.5 + github.com/aws/smithy-go v1.19.0 github.com/bmatcuk/doublestar/v4 v4.7.1 github.com/bombsimon/logrusr/v2 v2.0.1 github.com/bradleyfalzon/ghinstallation/v2 v2.12.0 @@ -70,6 +72,7 @@ require ( github.com/r3labs/diff v1.1.0 github.com/redis/go-redis/v9 v9.7.1 github.com/robfig/cron/v3 v3.0.1 + github.com/sethvargo/go-limiter v1.0.0 github.com/sirupsen/logrus v1.9.3 github.com/skratchdot/open-golang v0.0.0-20160302144031-75fb7ed4208c github.com/soheilhy/cmux v0.1.5 @@ -118,6 +121,7 @@ require ( github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.8.0 // indirect github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0 // indirect github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2 // indirect + github.com/PaesslerAG/gval v1.0.0 // indirect github.com/aws/aws-sdk-go-v2 v1.24.1 // indirect github.com/aws/aws-sdk-go-v2/config v1.25.12 // indirect github.com/aws/aws-sdk-go-v2/credentials v1.16.16 // indirect @@ -131,7 +135,6 @@ require ( github.com/aws/aws-sdk-go-v2/service/sso v1.18.7 // indirect github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.7 // indirect github.com/aws/aws-sdk-go-v2/service/sts v1.26.7 // indirect - github.com/aws/smithy-go v1.19.0 // indirect github.com/davidmz/go-pageant v1.0.2 // indirect github.com/distribution/reference v0.5.0 // indirect github.com/fxamacker/cbor/v2 v2.7.0 // indirect diff --git a/go.sum b/go.sum index 006f5742528d5..ef9c60b6cb2a5 100644 --- a/go.sum +++ b/go.sum @@ -59,6 +59,11 @@ github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5 github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= github.com/OvyFlash/telegram-bot-api/v5 v5.0.0-20240108230938-63e5c59035bf h1:a7VKhbjKYPO8twGy/1AxMpM2Fp0qT7bf25fmCVMVu4s= github.com/OvyFlash/telegram-bot-api/v5 v5.0.0-20240108230938-63e5c59035bf/go.mod h1:A2S0CWkNylc2phvKXWBBdD3K0iGnDBGbzRpISP2zBl8= +github.com/PaesslerAG/gval v1.0.0 h1:GEKnRwkWDdf9dOmKcNrar9EA1bz1z9DqPIO1+iLzhd8= +github.com/PaesslerAG/gval v1.0.0/go.mod h1:y/nm5yEyTeX6av0OfKJNp9rBNj2XrGhAf5+v24IBN1I= +github.com/PaesslerAG/jsonpath v0.1.0/go.mod h1:4BzmtoM/PI8fPO4aQGIusjGxGir2BzcV0grWtFzq1Y8= +github.com/PaesslerAG/jsonpath v0.1.1 h1:c1/AToHQMVsduPAa4Vh6xp2U0evy4t8SWp8imEsylIk= +github.com/PaesslerAG/jsonpath v0.1.1/go.mod h1:lVboNxFGal/VwW6d9JzIy56bUsYAP6tH/x80vjnCseY= github.com/PagerDuty/go-pagerduty v1.7.0 h1:S1NcMKECxT5hJwV4VT+QzeSsSiv4oWl1s2821dUqG/8= github.com/PagerDuty/go-pagerduty v1.7.0/go.mod h1:PuFyJKRz1liIAH4h5KVXVD18Obpp1ZXRdxHvmGXooro= github.com/ProtonMail/go-crypto v1.1.5 h1:eoAQfK2dwL+tFSFpr7TbOaPNUbPiJj4fLYwwGE1FQO4= @@ -872,6 +877,8 @@ github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0 github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8= github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= +github.com/sethvargo/go-limiter v1.0.0 h1:JqW13eWEMn0VFv86OKn8wiYJY/m250WoXdrjRV0kLe4= +github.com/sethvargo/go-limiter v1.0.0/go.mod h1:01b6tW25Ap+MeLYBuD4aHunMrJoNO5PVUFdS9rac3II= github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k= github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= diff --git a/hack/goreman-start.sh b/hack/goreman-start.sh index b5886084c7dff..e753150e31ad3 100644 --- a/hack/goreman-start.sh +++ b/hack/goreman-start.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -declare -a services=("controller" "api-server" "redis" "repo-server" "ui") +declare -a services=("controller" "api-server" "redis" "repo-server" "ui" "applicationset-controller") EXCLUDE=$exclude diff --git a/hack/installers/checksums/helm-v3.17.1-darwin-amd64.tar.gz.sha256 b/hack/installers/checksums/helm-v3.17.1-darwin-amd64.tar.gz.sha256 new file mode 100644 index 0000000000000..44bb6f2ff36a9 --- /dev/null +++ b/hack/installers/checksums/helm-v3.17.1-darwin-amd64.tar.gz.sha256 @@ -0,0 +1 @@ +aba59ba9511971a71943b5c76f15d52ace1681197bb3f71ed1f0b15caceacb2c helm-v3.17.1-darwin-amd64.tar.gz diff --git a/hack/installers/checksums/helm-v3.17.1-darwin-arm64.tar.gz.sha256 b/hack/installers/checksums/helm-v3.17.1-darwin-arm64.tar.gz.sha256 new file mode 100644 index 0000000000000..be019680885fd --- /dev/null +++ b/hack/installers/checksums/helm-v3.17.1-darwin-arm64.tar.gz.sha256 @@ -0,0 +1 @@ +b823a213d8d7937222becc63d9c7bb3d15a090e7ecd1f70f3a583ed39657e21b helm-v3.17.1-darwin-arm64.tar.gz diff --git a/hack/installers/checksums/helm-v3.17.1-linux-amd64.tar.gz.sha256 b/hack/installers/checksums/helm-v3.17.1-linux-amd64.tar.gz.sha256 new file mode 100644 index 0000000000000..4d39da141fe3d --- /dev/null +++ b/hack/installers/checksums/helm-v3.17.1-linux-amd64.tar.gz.sha256 @@ -0,0 +1 @@ +3b66f3cd28409f29832b1b35b43d9922959a32d795003149707fea84cbcd4469 helm-v3.17.1-linux-amd64.tar.gz diff --git a/hack/installers/checksums/helm-v3.17.1-linux-arm64.tar.gz.sha256 b/hack/installers/checksums/helm-v3.17.1-linux-arm64.tar.gz.sha256 new file mode 100644 index 0000000000000..c565a463a5a35 --- /dev/null +++ b/hack/installers/checksums/helm-v3.17.1-linux-arm64.tar.gz.sha256 @@ -0,0 +1 @@ +c86c9b23602d4abbfae39d9634e25ab1d0ea6c4c16c5b154113efe316a402547 helm-v3.17.1-linux-arm64.tar.gz diff --git a/hack/installers/checksums/helm-v3.17.1-linux-ppc64le.tar.gz.sha256 b/hack/installers/checksums/helm-v3.17.1-linux-ppc64le.tar.gz.sha256 new file mode 100644 index 0000000000000..8ffcd2a5d80eb --- /dev/null +++ b/hack/installers/checksums/helm-v3.17.1-linux-ppc64le.tar.gz.sha256 @@ -0,0 +1 @@ +4223394f3fca82a7f8e8d083caf6faf0ee0639d8f235071334579237078a2c2e helm-v3.17.1-linux-ppc64le.tar.gz diff --git a/hack/installers/checksums/helm-v3.17.1-linux-s390x.tar.gz.sha256 b/hack/installers/checksums/helm-v3.17.1-linux-s390x.tar.gz.sha256 new file mode 100644 index 0000000000000..60d071db69473 --- /dev/null +++ b/hack/installers/checksums/helm-v3.17.1-linux-s390x.tar.gz.sha256 @@ -0,0 +1 @@ +fe47e5ee8abd6baef01bb1c4fc995343121bf5fc7dead1f67e97484a441ba9e8 helm-v3.17.1-linux-s390x.tar.gz diff --git a/hack/tool-versions.sh b/hack/tool-versions.sh index 5ff690de480ad..820fa336c251d 100644 --- a/hack/tool-versions.sh +++ b/hack/tool-versions.sh @@ -11,7 +11,7 @@ # Use ./hack/installers/checksums/add-helm-checksums.sh and # add-kustomize-checksums.sh to help download checksums. ############################################################################### -helm3_version=3.16.3 +helm3_version=3.17.1 kubectl_version=1.17.8 kubectx_version=0.6.3 kustomize5_version=5.4.3 diff --git a/hack/update-manifests.sh b/hack/update-manifests.sh index 815efbd1c49fd..a80edf0311e95 100755 --- a/hack/update-manifests.sh +++ b/hack/update-manifests.sh @@ -12,16 +12,17 @@ KUSTOMIZE=kustomize cd ${SRCROOT}/manifests/ha/base/redis-ha && ./generate.sh -IMAGE_NAMESPACE="${IMAGE_NAMESPACE:-quay.io/argoproj}" +IMAGE_NAMESPACE="${IMAGE_NAMESPACE:-quay.io/codefresh}" IMAGE_TAG="${IMAGE_TAG:-}" # if the tag has not been declared, and we are on a release branch, use the VERSION file. +# CODEFRESH: we always want to generate the manifests with the version from the VERSION file, so we will always set IMAGE_TAG to the version in the VERSION file. if [ "$IMAGE_TAG" = "" ]; then - branch=$(git rev-parse --abbrev-ref HEAD) - if [[ $branch = release-* ]]; then + # branch=$(git rev-parse --abbrev-ref HEAD) + # if [[ $branch = sync-* ]]; then pwd IMAGE_TAG=v$(cat $SRCROOT/VERSION) - fi + # fi fi # otherwise, use latest if [ "$IMAGE_TAG" = "" ]; then diff --git a/manifests/base/acr-controller/acr-controller-deployment.yaml b/manifests/base/acr-controller/acr-controller-deployment.yaml new file mode 100644 index 0000000000000..d75ab9f05b55f --- /dev/null +++ b/manifests/base/acr-controller/acr-controller-deployment.yaml @@ -0,0 +1,88 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/name: acr-controller + app.kubernetes.io/part-of: argocd + app.kubernetes.io/component: acr-controller + name: acr-controller +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/name: acr-controller + template: + metadata: + labels: + app.kubernetes.io/name: acr-controller + spec: + serviceAccountName: acr-controller + containers: + - name: acr-controller + image: quay.io/argoproj/argocd:latest + imagePullPolicy: Always + args: + - /usr/local/bin/argocd-application-change-revision-controller + env: + - name: ARGOCD_SERVER + value: "http://argocd-server:80" + - name: ARGOCD_TOKEN + valueFrom: + secretKeyRef: + key: token + name: argocd-token + - name: ARGOCD_SERVER_ROOTPATH + valueFrom: + configMapKeyRef: + key: server.rootpath + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_NAMESPACES + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: application.namespaces + optional: true + - name: ACR_CONTROLLER_LOGFORMAT + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: acr.log.format + optional: true + - name: ACR_CONTROLLER_LOG_LEVEL + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: acr.log.level + optional: true + - name: ACR_CONTROLLER_LISTEN_ADDRESS + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: acr.listen.address + optional: true + ports: + - containerPort: 8090 + name: health + livenessProbe: + httpGet: + path: /healthz?full=true + port: health + initialDelaySeconds: 3 + periodSeconds: 30 + timeoutSeconds: 5 + readinessProbe: + httpGet: + path: /healthz + port: health + initialDelaySeconds: 3 + periodSeconds: 30 + securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + runAsNonRoot: true + capabilities: + drop: + - ALL + seccompProfile: + type: RuntimeDefault diff --git a/manifests/base/acr-controller/acr-controller-role.yaml b/manifests/base/acr-controller/acr-controller-role.yaml new file mode 100644 index 0000000000000..3a1e1991680e7 --- /dev/null +++ b/manifests/base/acr-controller/acr-controller-role.yaml @@ -0,0 +1,43 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + labels: + app.kubernetes.io/name: acr-controller + app.kubernetes.io/part-of: argocd + app.kubernetes.io/component: acr-controller + name: acr-controller +rules: +- apiGroups: + - "" + resources: + - secrets + - configmaps + verbs: + - create + - get + - list + - watch + - update + - patch + - delete +- apiGroups: + - argoproj.io + resources: + - applications + - appprojects + - applicationsets + verbs: + - create + - get + - list + - watch + - update + - delete + - patch +- apiGroups: + - "" + resources: + - events + verbs: + - create + - list diff --git a/manifests/base/acr-controller/acr-controller-rolebinding.yaml b/manifests/base/acr-controller/acr-controller-rolebinding.yaml new file mode 100644 index 0000000000000..e70280a6bc3f9 --- /dev/null +++ b/manifests/base/acr-controller/acr-controller-rolebinding.yaml @@ -0,0 +1,15 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + app.kubernetes.io/name: acr-controller + app.kubernetes.io/part-of: argocd + app.kubernetes.io/component: acr-controller + name: acr-controller +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: acr-controller +subjects: +- kind: ServiceAccount + name: acr-controller diff --git a/manifests/base/acr-controller/acr-controller-sa.yaml b/manifests/base/acr-controller/acr-controller-sa.yaml new file mode 100644 index 0000000000000..0042922267f34 --- /dev/null +++ b/manifests/base/acr-controller/acr-controller-sa.yaml @@ -0,0 +1,8 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/name: acr-controller + app.kubernetes.io/part-of: argocd + app.kubernetes.io/component: acr-controller + name: acr-controller diff --git a/manifests/base/acr-controller/kustomization.yaml b/manifests/base/acr-controller/kustomization.yaml new file mode 100644 index 0000000000000..93d7ff439875f --- /dev/null +++ b/manifests/base/acr-controller/kustomization.yaml @@ -0,0 +1,8 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +resources: +- acr-controller-deployment.yaml +- acr-controller-role.yaml +- acr-controller-rolebinding.yaml +- acr-controller-sa.yaml diff --git a/manifests/base/event-reporter/event-reporter-metrics.yaml b/manifests/base/event-reporter/event-reporter-metrics.yaml new file mode 100644 index 0000000000000..bb9e261d8321e --- /dev/null +++ b/manifests/base/event-reporter/event-reporter-metrics.yaml @@ -0,0 +1,16 @@ +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/name: event-reporter-metrics + app.kubernetes.io/part-of: argocd + app.kubernetes.io/component: event-reporter + name: event-reporter-metrics +spec: + ports: + - name: metrics + protocol: TCP + port: 8087 + targetPort: 8087 + selector: + app.kubernetes.io/name: event-reporter diff --git a/manifests/base/event-reporter/event-reporter-role.yaml b/manifests/base/event-reporter/event-reporter-role.yaml new file mode 100644 index 0000000000000..ddb1508d89690 --- /dev/null +++ b/manifests/base/event-reporter/event-reporter-role.yaml @@ -0,0 +1,43 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + labels: + app.kubernetes.io/name: event-reporter + app.kubernetes.io/part-of: argocd + app.kubernetes.io/component: event-reporter + name: event-reporter +rules: +- apiGroups: + - "" + resources: + - secrets + - configmaps + verbs: + - create + - get + - list + - watch + - update + - patch + - delete +- apiGroups: + - argoproj.io + resources: + - applications + - appprojects + - applicationsets + verbs: + - create + - get + - list + - watch + - update + - delete + - patch +- apiGroups: + - "" + resources: + - events + verbs: + - create + - list diff --git a/manifests/base/event-reporter/event-reporter-rolebinding.yaml b/manifests/base/event-reporter/event-reporter-rolebinding.yaml new file mode 100644 index 0000000000000..1bbc0851f803d --- /dev/null +++ b/manifests/base/event-reporter/event-reporter-rolebinding.yaml @@ -0,0 +1,15 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + app.kubernetes.io/name: event-reporter + app.kubernetes.io/part-of: argocd + app.kubernetes.io/component: event-reporter + name: event-reporter +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: event-reporter +subjects: +- kind: ServiceAccount + name: event-reporter diff --git a/manifests/base/event-reporter/event-reporter-sa.yaml b/manifests/base/event-reporter/event-reporter-sa.yaml new file mode 100644 index 0000000000000..51d4e39fbb50e --- /dev/null +++ b/manifests/base/event-reporter/event-reporter-sa.yaml @@ -0,0 +1,8 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/name: event-reporter + app.kubernetes.io/part-of: argocd + app.kubernetes.io/component: event-reporter + name: event-reporter diff --git a/manifests/base/event-reporter/event-reporter-service.yaml b/manifests/base/event-reporter/event-reporter-service.yaml new file mode 100644 index 0000000000000..6a89a2f9d17db --- /dev/null +++ b/manifests/base/event-reporter/event-reporter-service.yaml @@ -0,0 +1,20 @@ +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/name: event-reporter + app.kubernetes.io/part-of: argocd + app.kubernetes.io/component: event-reporter + name: event-reporter +spec: + ports: + - name: http + protocol: TCP + port: 80 + targetPort: 8088 + - name: https + protocol: TCP + port: 443 + targetPort: 8088 + selector: + app.kubernetes.io/name: event-reporter diff --git a/manifests/base/event-reporter/event-reporter-statefulset.yaml b/manifests/base/event-reporter/event-reporter-statefulset.yaml new file mode 100644 index 0000000000000..4174f47e4848b --- /dev/null +++ b/manifests/base/event-reporter/event-reporter-statefulset.yaml @@ -0,0 +1,174 @@ +apiVersion: apps/v1 +kind: StatefulSet +metadata: + labels: + app.kubernetes.io/name: event-reporter + app.kubernetes.io/part-of: argocd + app.kubernetes.io/component: event-reporter + name: event-reporter +spec: + replicas: 5 + serviceName: event-reporter + selector: + matchLabels: + app.kubernetes.io/name: event-reporter + template: + metadata: + labels: + app.kubernetes.io/name: event-reporter + spec: + serviceAccountName: event-reporter + containers: + - name: event-reporter + image: quay.io/argoproj/argocd:latest + imagePullPolicy: Always + args: + - /usr/local/bin/event-reporter-server + env: + - name: EVENT_REPORTER_REPLICAS + value: "5" + - name: ARGOCD_TOKEN + valueFrom: + secretKeyRef: + key: token + name: argocd-token + - name: ARGOCD_APPLICATION_NAMESPACES + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: application.namespaces + optional: true + - name: CODEFRESH_URL + valueFrom: + configMapKeyRef: + name: codefresh-cm + key: base-url + optional: true + - name: CODEFRESH_TOKEN + valueFrom: + secretKeyRef: + key: token + name: codefresh-token + - name: EVENT_REPORTER_INSECURE + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: event-reporter.insecure + optional: true + - name: EVENT_REPORTER_LOGFORMAT + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: event-reporter.log.format + optional: true + - name: EVENT_REPORTER_LOG_LEVEL + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: event-reporter.log.level + optional: true + - name: EVENT_REPORTER_REPO_SERVER + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: repo.server + optional: true + - name: EVENT_REPORTER_REPO_SERVER_TIMEOUT_SECONDS + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: event-reporter.repo.server.timeout.seconds + optional: true + - name: EVENT_REPORTER_REPO_SERVER_PLAINTEXT + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: event-reporter.repo.server.plaintext + optional: true + - name: REDIS_SERVER + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: redis.server + optional: true + - name: REDISDB + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: redis.db + optional: true + - name: EVENT_REPORTER_LISTEN_ADDRESS + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: event-reporter.listen.address + optional: true + - name: EVENT_REPORTER_METRICS_LISTEN_ADDRESS + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: event-reporter.metrics.listen.address + optional: true + volumeMounts: + - name: argocd-repo-server-tls + mountPath: /app/config/server/tls + - mountPath: /tmp + name: tmp + ports: + - containerPort: 8088 + name: health + - containerPort: 8087 + name: metrics + livenessProbe: + httpGet: + path: /healthz?full=true + port: health + initialDelaySeconds: 3 + periodSeconds: 30 + timeoutSeconds: 5 + readinessProbe: + httpGet: + path: /healthz + port: health + initialDelaySeconds: 3 + periodSeconds: 30 + securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + runAsNonRoot: true + capabilities: + drop: + - ALL + seccompProfile: + type: RuntimeDefault + volumes: + - emptyDir: {} + name: plugins-home + - emptyDir: {} + name: tmp + - name: argocd-repo-server-tls + secret: + secretName: argocd-repo-server-tls + optional: true + items: + - key: tls.crt + path: tls.crt + - key: tls.key + path: tls.key + - key: ca.crt + path: ca.crt + affinity: + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 100 + podAffinityTerm: + labelSelector: + matchLabels: + app.kubernetes.io/name: event-reporter + topologyKey: kubernetes.io/hostname + - weight: 5 + podAffinityTerm: + labelSelector: + matchLabels: + app.kubernetes.io/part-of: argocd + topologyKey: kubernetes.io/hostname diff --git a/manifests/base/event-reporter/kustomization.yaml b/manifests/base/event-reporter/kustomization.yaml new file mode 100644 index 0000000000000..eb7c1067f0008 --- /dev/null +++ b/manifests/base/event-reporter/kustomization.yaml @@ -0,0 +1,10 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +resources: +- event-reporter-statefulset.yaml +- event-reporter-role.yaml +- event-reporter-rolebinding.yaml +- event-reporter-sa.yaml +- event-reporter-service.yaml +- event-reporter-metrics.yaml \ No newline at end of file diff --git a/manifests/base/kustomization.yaml b/manifests/base/kustomization.yaml index 4acd59a29b8a8..6a28f4000367d 100644 --- a/manifests/base/kustomization.yaml +++ b/manifests/base/kustomization.yaml @@ -4,8 +4,8 @@ kind: Kustomization images: - name: quay.io/argoproj/argocd - newName: quay.io/argoproj/argocd - newTag: v2.14.9 + newName: quay.io/codefresh/argocd + newTag: v2.14.10 resources: - ./application-controller - ./dex diff --git a/manifests/core-install-with-hydrator.yaml b/manifests/core-install-with-hydrator.yaml index 474e91659786c..e6d8fb7f9575f 100644 --- a/manifests/core-install-with-hydrator.yaml +++ b/manifests/core-install-with-hydrator.yaml @@ -120,6 +120,12 @@ spec: attempts format: int64 type: integer + changeRevision: + type: string + changeRevisions: + items: + type: string + type: array dryRun: description: DryRun specifies to perform a `kubectl apply --dry-run` without actually performing the sync @@ -2855,6 +2861,12 @@ spec: of auto-heal attempts format: int64 type: integer + changeRevision: + type: string + changeRevisions: + items: + type: string + type: array dryRun: description: DryRun specifies to perform a `kubectl apply --dry-run` without actually performing the sync @@ -24165,7 +24177,7 @@ spec: key: applicationsetcontroller.requeue.after name: argocd-cmd-params-cm optional: true - image: quay.io/argoproj/argocd:v2.14.9 + image: quay.io/codefresh/argocd:v2.14.10 imagePullPolicy: Always name: argocd-applicationset-controller ports: @@ -24435,7 +24447,7 @@ spec: - argocd - admin - redis-initial-password - image: quay.io/argoproj/argocd:v2.14.9 + image: quay.io/codefresh/argocd:v2.14.10 imagePullPolicy: IfNotPresent name: secret-init securityContext: @@ -24696,7 +24708,7 @@ spec: value: /helm-working-dir - name: HELM_DATA_HOME value: /helm-working-dir - image: quay.io/argoproj/argocd:v2.14.9 + image: quay.io/codefresh/argocd:v2.14.10 imagePullPolicy: Always livenessProbe: failureThreshold: 3 @@ -24748,7 +24760,7 @@ spec: - -n - /usr/local/bin/argocd - /var/run/argocd/argocd-cmp-server - image: quay.io/argoproj/argocd:v2.14.9 + image: quay.io/codefresh/argocd:v2.14.10 name: copyutil securityContext: allowPrivilegeEscalation: false @@ -25066,7 +25078,7 @@ spec: optional: true - name: KUBECACHEDIR value: /tmp/kubecache - image: quay.io/argoproj/argocd:v2.14.9 + image: quay.io/codefresh/argocd:v2.14.10 imagePullPolicy: Always name: argocd-application-controller ports: diff --git a/manifests/core-install.yaml b/manifests/core-install.yaml index 15623f0c63f0f..310aabf538271 100644 --- a/manifests/core-install.yaml +++ b/manifests/core-install.yaml @@ -120,6 +120,12 @@ spec: attempts format: int64 type: integer + changeRevision: + type: string + changeRevisions: + items: + type: string + type: array dryRun: description: DryRun specifies to perform a `kubectl apply --dry-run` without actually performing the sync @@ -2855,6 +2861,12 @@ spec: of auto-heal attempts format: int64 type: integer + changeRevision: + type: string + changeRevisions: + items: + type: string + type: array dryRun: description: DryRun specifies to perform a `kubectl apply --dry-run` without actually performing the sync @@ -24133,7 +24145,7 @@ spec: key: applicationsetcontroller.requeue.after name: argocd-cmd-params-cm optional: true - image: quay.io/argoproj/argocd:v2.14.9 + image: quay.io/codefresh/argocd:v2.14.10 imagePullPolicy: Always name: argocd-applicationset-controller ports: @@ -24253,7 +24265,7 @@ spec: - argocd - admin - redis-initial-password - image: quay.io/argoproj/argocd:v2.14.9 + image: quay.io/codefresh/argocd:v2.14.10 imagePullPolicy: IfNotPresent name: secret-init securityContext: @@ -24514,7 +24526,7 @@ spec: value: /helm-working-dir - name: HELM_DATA_HOME value: /helm-working-dir - image: quay.io/argoproj/argocd:v2.14.9 + image: quay.io/codefresh/argocd:v2.14.10 imagePullPolicy: Always livenessProbe: failureThreshold: 3 @@ -24566,7 +24578,7 @@ spec: - -n - /usr/local/bin/argocd - /var/run/argocd/argocd-cmp-server - image: quay.io/argoproj/argocd:v2.14.9 + image: quay.io/codefresh/argocd:v2.14.10 name: copyutil securityContext: allowPrivilegeEscalation: false @@ -24884,7 +24896,7 @@ spec: optional: true - name: KUBECACHEDIR value: /tmp/kubecache - image: quay.io/argoproj/argocd:v2.14.9 + image: quay.io/codefresh/argocd:v2.14.10 imagePullPolicy: Always name: argocd-application-controller ports: diff --git a/manifests/core-install/kustomization.yaml b/manifests/core-install/kustomization.yaml index 06d694892dff1..ff0965ba9f2fc 100644 --- a/manifests/core-install/kustomization.yaml +++ b/manifests/core-install/kustomization.yaml @@ -11,5 +11,5 @@ resources: - ../base/redis images: - name: quay.io/argoproj/argocd - newName: quay.io/argoproj/argocd - newTag: v2.14.9 + newName: quay.io/codefresh/argocd + newTag: v2.14.10 diff --git a/manifests/crds/application-crd.yaml b/manifests/crds/application-crd.yaml index e2dac9a68be74..f416f936383ab 100644 --- a/manifests/crds/application-crd.yaml +++ b/manifests/crds/application-crd.yaml @@ -119,6 +119,12 @@ spec: attempts format: int64 type: integer + changeRevision: + type: string + changeRevisions: + items: + type: string + type: array dryRun: description: DryRun specifies to perform a `kubectl apply --dry-run` without actually performing the sync @@ -2854,6 +2860,12 @@ spec: of auto-heal attempts format: int64 type: integer + changeRevision: + type: string + changeRevisions: + items: + type: string + type: array dryRun: description: DryRun specifies to perform a `kubectl apply --dry-run` without actually performing the sync diff --git a/manifests/ha/base/kustomization.yaml b/manifests/ha/base/kustomization.yaml index 6015a7f32e9f3..0ce90f1bbe94c 100644 --- a/manifests/ha/base/kustomization.yaml +++ b/manifests/ha/base/kustomization.yaml @@ -11,8 +11,8 @@ patches: images: - name: quay.io/argoproj/argocd - newName: quay.io/argoproj/argocd - newTag: v2.14.9 + newName: quay.io/codefresh/argocd + newTag: v2.14.10 resources: - ../../base/application-controller - ../../base/applicationset-controller diff --git a/manifests/ha/base/redis-ha/chart/upstream.yaml b/manifests/ha/base/redis-ha/chart/upstream.yaml index 79e356f983762..c43520bd1ef3a 100644 --- a/manifests/ha/base/redis-ha/chart/upstream.yaml +++ b/manifests/ha/base/redis-ha/chart/upstream.yaml @@ -1100,13 +1100,7 @@ spec: args: - /readonly/haproxy_init.sh securityContext: - allowPrivilegeEscalation: false - capabilities: - drop: - - ALL - runAsNonRoot: true - seccompProfile: - type: RuntimeDefault + null volumeMounts: - name: config-volume mountPath: /readonly @@ -1118,13 +1112,7 @@ spec: image: public.ecr.aws/docker/library/haproxy:2.6.17-alpine imagePullPolicy: IfNotPresent securityContext: - allowPrivilegeEscalation: false - capabilities: - drop: - - ALL - runAsNonRoot: true - seccompProfile: - type: RuntimeDefault + null env: - name: AUTH valueFrom: @@ -1228,14 +1216,7 @@ spec: args: - /readonly-config/init.sh securityContext: - allowPrivilegeEscalation: false - capabilities: - drop: - - ALL - runAsNonRoot: true - runAsUser: 1000 - seccompProfile: - type: RuntimeDefault + null env: - name: SENTINEL_ID_0 value: 3c0d9c0320bb34888c2df5757c718ce6ca992ce6 @@ -1265,14 +1246,7 @@ spec: args: - /data/conf/redis.conf securityContext: - allowPrivilegeEscalation: false - capabilities: - drop: - - ALL - runAsNonRoot: true - runAsUser: 1000 - seccompProfile: - type: RuntimeDefault + null env: - name: AUTH valueFrom: @@ -1328,14 +1302,7 @@ spec: args: - /data/conf/sentinel.conf securityContext: - allowPrivilegeEscalation: false - capabilities: - drop: - - ALL - runAsNonRoot: true - runAsUser: 1000 - seccompProfile: - type: RuntimeDefault + null env: - name: AUTH valueFrom: @@ -1390,14 +1357,7 @@ spec: args: - /readonly-config/fix-split-brain.sh securityContext: - allowPrivilegeEscalation: false - capabilities: - drop: - - ALL - runAsNonRoot: true - runAsUser: 1000 - seccompProfile: - type: RuntimeDefault + null env: - name: SENTINEL_ID_0 value: 3c0d9c0320bb34888c2df5757c718ce6ca992ce6 diff --git a/manifests/ha/install-with-hydrator.yaml b/manifests/ha/install-with-hydrator.yaml index 112d012521751..07a5b974a5f20 100644 --- a/manifests/ha/install-with-hydrator.yaml +++ b/manifests/ha/install-with-hydrator.yaml @@ -120,6 +120,12 @@ spec: attempts format: int64 type: integer + changeRevision: + type: string + changeRevisions: + items: + type: string + type: array dryRun: description: DryRun specifies to perform a `kubectl apply --dry-run` without actually performing the sync @@ -2855,6 +2861,12 @@ spec: of auto-heal attempts format: int64 type: integer + changeRevision: + type: string + changeRevisions: + items: + type: string + type: array dryRun: description: DryRun specifies to perform a `kubectl apply --dry-run` without actually performing the sync @@ -25506,7 +25518,7 @@ spec: key: applicationsetcontroller.requeue.after name: argocd-cmd-params-cm optional: true - image: quay.io/argoproj/argocd:v2.14.9 + image: quay.io/codefresh/argocd:v2.14.10 imagePullPolicy: Always name: argocd-applicationset-controller ports: @@ -25793,7 +25805,7 @@ spec: - -n - /usr/local/bin/argocd - /shared/argocd-dex - image: quay.io/argoproj/argocd:v2.14.9 + image: quay.io/codefresh/argocd:v2.14.10 imagePullPolicy: Always name: copyutil securityContext: @@ -25883,7 +25895,7 @@ spec: key: notificationscontroller.repo.server.plaintext name: argocd-cmd-params-cm optional: true - image: quay.io/argoproj/argocd:v2.14.9 + image: quay.io/codefresh/argocd:v2.14.10 imagePullPolicy: Always livenessProbe: tcpSocket: @@ -26004,7 +26016,7 @@ spec: - argocd - admin - redis-initial-password - image: quay.io/argoproj/argocd:v2.14.9 + image: quay.io/codefresh/argocd:v2.14.10 imagePullPolicy: IfNotPresent name: secret-init securityContext: @@ -26291,7 +26303,7 @@ spec: value: /helm-working-dir - name: HELM_DATA_HOME value: /helm-working-dir - image: quay.io/argoproj/argocd:v2.14.9 + image: quay.io/codefresh/argocd:v2.14.10 imagePullPolicy: Always livenessProbe: failureThreshold: 3 @@ -26343,7 +26355,7 @@ spec: - -n - /usr/local/bin/argocd - /var/run/argocd/argocd-cmp-server - image: quay.io/argoproj/argocd:v2.14.9 + image: quay.io/codefresh/argocd:v2.14.10 name: copyutil securityContext: allowPrivilegeEscalation: false @@ -26705,7 +26717,7 @@ spec: key: hydrator.enabled name: argocd-cmd-params-cm optional: true - image: quay.io/argoproj/argocd:v2.14.9 + image: quay.io/codefresh/argocd:v2.14.10 imagePullPolicy: Always livenessProbe: httpGet: @@ -27059,7 +27071,7 @@ spec: optional: true - name: KUBECACHEDIR value: /tmp/kubecache - image: quay.io/argoproj/argocd:v2.14.9 + image: quay.io/codefresh/argocd:v2.14.10 imagePullPolicy: Always name: argocd-application-controller ports: diff --git a/manifests/ha/install.yaml b/manifests/ha/install.yaml index 0f2b94615ca4d..ea4c83f92c2cd 100644 --- a/manifests/ha/install.yaml +++ b/manifests/ha/install.yaml @@ -120,6 +120,12 @@ spec: attempts format: int64 type: integer + changeRevision: + type: string + changeRevisions: + items: + type: string + type: array dryRun: description: DryRun specifies to perform a `kubectl apply --dry-run` without actually performing the sync @@ -2855,6 +2861,12 @@ spec: of auto-heal attempts format: int64 type: integer + changeRevision: + type: string + changeRevisions: + items: + type: string + type: array dryRun: description: DryRun specifies to perform a `kubectl apply --dry-run` without actually performing the sync @@ -25476,7 +25488,7 @@ spec: key: applicationsetcontroller.requeue.after name: argocd-cmd-params-cm optional: true - image: quay.io/argoproj/argocd:v2.14.9 + image: quay.io/codefresh/argocd:v2.14.10 imagePullPolicy: Always name: argocd-applicationset-controller ports: @@ -25613,7 +25625,7 @@ spec: - -n - /usr/local/bin/argocd - /shared/argocd-dex - image: quay.io/argoproj/argocd:v2.14.9 + image: quay.io/codefresh/argocd:v2.14.10 imagePullPolicy: Always name: copyutil securityContext: @@ -25703,7 +25715,7 @@ spec: key: notificationscontroller.repo.server.plaintext name: argocd-cmd-params-cm optional: true - image: quay.io/argoproj/argocd:v2.14.9 + image: quay.io/codefresh/argocd:v2.14.10 imagePullPolicy: Always livenessProbe: tcpSocket: @@ -25824,7 +25836,7 @@ spec: - argocd - admin - redis-initial-password - image: quay.io/argoproj/argocd:v2.14.9 + image: quay.io/codefresh/argocd:v2.14.10 imagePullPolicy: IfNotPresent name: secret-init securityContext: @@ -26111,7 +26123,7 @@ spec: value: /helm-working-dir - name: HELM_DATA_HOME value: /helm-working-dir - image: quay.io/argoproj/argocd:v2.14.9 + image: quay.io/codefresh/argocd:v2.14.10 imagePullPolicy: Always livenessProbe: failureThreshold: 3 @@ -26163,7 +26175,7 @@ spec: - -n - /usr/local/bin/argocd - /var/run/argocd/argocd-cmp-server - image: quay.io/argoproj/argocd:v2.14.9 + image: quay.io/codefresh/argocd:v2.14.10 name: copyutil securityContext: allowPrivilegeEscalation: false @@ -26525,7 +26537,7 @@ spec: key: hydrator.enabled name: argocd-cmd-params-cm optional: true - image: quay.io/argoproj/argocd:v2.14.9 + image: quay.io/codefresh/argocd:v2.14.10 imagePullPolicy: Always livenessProbe: httpGet: @@ -26879,7 +26891,7 @@ spec: optional: true - name: KUBECACHEDIR value: /tmp/kubecache - image: quay.io/argoproj/argocd:v2.14.9 + image: quay.io/codefresh/argocd:v2.14.10 imagePullPolicy: Always name: argocd-application-controller ports: diff --git a/manifests/ha/namespace-install-with-hydrator.yaml b/manifests/ha/namespace-install-with-hydrator.yaml index c1cf19e54be6f..58fd700470f49 100644 --- a/manifests/ha/namespace-install-with-hydrator.yaml +++ b/manifests/ha/namespace-install-with-hydrator.yaml @@ -1736,7 +1736,7 @@ spec: key: applicationsetcontroller.requeue.after name: argocd-cmd-params-cm optional: true - image: quay.io/argoproj/argocd:v2.14.9 + image: quay.io/codefresh/argocd:v2.14.10 imagePullPolicy: Always name: argocd-applicationset-controller ports: @@ -2023,7 +2023,7 @@ spec: - -n - /usr/local/bin/argocd - /shared/argocd-dex - image: quay.io/argoproj/argocd:v2.14.9 + image: quay.io/codefresh/argocd:v2.14.10 imagePullPolicy: Always name: copyutil securityContext: @@ -2113,7 +2113,7 @@ spec: key: notificationscontroller.repo.server.plaintext name: argocd-cmd-params-cm optional: true - image: quay.io/argoproj/argocd:v2.14.9 + image: quay.io/codefresh/argocd:v2.14.10 imagePullPolicy: Always livenessProbe: tcpSocket: @@ -2234,7 +2234,7 @@ spec: - argocd - admin - redis-initial-password - image: quay.io/argoproj/argocd:v2.14.9 + image: quay.io/codefresh/argocd:v2.14.10 imagePullPolicy: IfNotPresent name: secret-init securityContext: @@ -2521,7 +2521,7 @@ spec: value: /helm-working-dir - name: HELM_DATA_HOME value: /helm-working-dir - image: quay.io/argoproj/argocd:v2.14.9 + image: quay.io/codefresh/argocd:v2.14.10 imagePullPolicy: Always livenessProbe: failureThreshold: 3 @@ -2573,7 +2573,7 @@ spec: - -n - /usr/local/bin/argocd - /var/run/argocd/argocd-cmp-server - image: quay.io/argoproj/argocd:v2.14.9 + image: quay.io/codefresh/argocd:v2.14.10 name: copyutil securityContext: allowPrivilegeEscalation: false @@ -2935,7 +2935,7 @@ spec: key: hydrator.enabled name: argocd-cmd-params-cm optional: true - image: quay.io/argoproj/argocd:v2.14.9 + image: quay.io/codefresh/argocd:v2.14.10 imagePullPolicy: Always livenessProbe: httpGet: @@ -3289,7 +3289,7 @@ spec: optional: true - name: KUBECACHEDIR value: /tmp/kubecache - image: quay.io/argoproj/argocd:v2.14.9 + image: quay.io/codefresh/argocd:v2.14.10 imagePullPolicy: Always name: argocd-application-controller ports: diff --git a/manifests/ha/namespace-install.yaml b/manifests/ha/namespace-install.yaml index 3b5fabd3807b1..5463745f0d335 100644 --- a/manifests/ha/namespace-install.yaml +++ b/manifests/ha/namespace-install.yaml @@ -1706,7 +1706,7 @@ spec: key: applicationsetcontroller.requeue.after name: argocd-cmd-params-cm optional: true - image: quay.io/argoproj/argocd:v2.14.9 + image: quay.io/codefresh/argocd:v2.14.10 imagePullPolicy: Always name: argocd-applicationset-controller ports: @@ -1843,7 +1843,7 @@ spec: - -n - /usr/local/bin/argocd - /shared/argocd-dex - image: quay.io/argoproj/argocd:v2.14.9 + image: quay.io/codefresh/argocd:v2.14.10 imagePullPolicy: Always name: copyutil securityContext: @@ -1933,7 +1933,7 @@ spec: key: notificationscontroller.repo.server.plaintext name: argocd-cmd-params-cm optional: true - image: quay.io/argoproj/argocd:v2.14.9 + image: quay.io/codefresh/argocd:v2.14.10 imagePullPolicy: Always livenessProbe: tcpSocket: @@ -2054,7 +2054,7 @@ spec: - argocd - admin - redis-initial-password - image: quay.io/argoproj/argocd:v2.14.9 + image: quay.io/codefresh/argocd:v2.14.10 imagePullPolicy: IfNotPresent name: secret-init securityContext: @@ -2341,7 +2341,7 @@ spec: value: /helm-working-dir - name: HELM_DATA_HOME value: /helm-working-dir - image: quay.io/argoproj/argocd:v2.14.9 + image: quay.io/codefresh/argocd:v2.14.10 imagePullPolicy: Always livenessProbe: failureThreshold: 3 @@ -2393,7 +2393,7 @@ spec: - -n - /usr/local/bin/argocd - /var/run/argocd/argocd-cmp-server - image: quay.io/argoproj/argocd:v2.14.9 + image: quay.io/codefresh/argocd:v2.14.10 name: copyutil securityContext: allowPrivilegeEscalation: false @@ -2755,7 +2755,7 @@ spec: key: hydrator.enabled name: argocd-cmd-params-cm optional: true - image: quay.io/argoproj/argocd:v2.14.9 + image: quay.io/codefresh/argocd:v2.14.10 imagePullPolicy: Always livenessProbe: httpGet: @@ -3109,7 +3109,7 @@ spec: optional: true - name: KUBECACHEDIR value: /tmp/kubecache - image: quay.io/argoproj/argocd:v2.14.9 + image: quay.io/codefresh/argocd:v2.14.10 imagePullPolicy: Always name: argocd-application-controller ports: diff --git a/manifests/install-with-hydrator.yaml b/manifests/install-with-hydrator.yaml index 8db301eee8d36..bdc84fa833d2b 100644 --- a/manifests/install-with-hydrator.yaml +++ b/manifests/install-with-hydrator.yaml @@ -120,6 +120,12 @@ spec: attempts format: int64 type: integer + changeRevision: + type: string + changeRevisions: + items: + type: string + type: array dryRun: description: DryRun specifies to perform a `kubectl apply --dry-run` without actually performing the sync @@ -2855,6 +2861,12 @@ spec: of auto-heal attempts format: int64 type: integer + changeRevision: + type: string + changeRevisions: + items: + type: string + type: array dryRun: description: DryRun specifies to perform a `kubectl apply --dry-run` without actually performing the sync @@ -24625,7 +24637,7 @@ spec: key: applicationsetcontroller.requeue.after name: argocd-cmd-params-cm optional: true - image: quay.io/argoproj/argocd:v2.14.9 + image: quay.io/codefresh/argocd:v2.14.10 imagePullPolicy: Always name: argocd-applicationset-controller ports: @@ -24912,7 +24924,7 @@ spec: - -n - /usr/local/bin/argocd - /shared/argocd-dex - image: quay.io/argoproj/argocd:v2.14.9 + image: quay.io/codefresh/argocd:v2.14.10 imagePullPolicy: Always name: copyutil securityContext: @@ -25002,7 +25014,7 @@ spec: key: notificationscontroller.repo.server.plaintext name: argocd-cmd-params-cm optional: true - image: quay.io/argoproj/argocd:v2.14.9 + image: quay.io/codefresh/argocd:v2.14.10 imagePullPolicy: Always livenessProbe: tcpSocket: @@ -25104,7 +25116,7 @@ spec: - argocd - admin - redis-initial-password - image: quay.io/argoproj/argocd:v2.14.9 + image: quay.io/codefresh/argocd:v2.14.10 imagePullPolicy: IfNotPresent name: secret-init securityContext: @@ -25365,7 +25377,7 @@ spec: value: /helm-working-dir - name: HELM_DATA_HOME value: /helm-working-dir - image: quay.io/argoproj/argocd:v2.14.9 + image: quay.io/codefresh/argocd:v2.14.10 imagePullPolicy: Always livenessProbe: failureThreshold: 3 @@ -25417,7 +25429,7 @@ spec: - -n - /usr/local/bin/argocd - /var/run/argocd/argocd-cmp-server - image: quay.io/argoproj/argocd:v2.14.9 + image: quay.io/codefresh/argocd:v2.14.10 name: copyutil securityContext: allowPrivilegeEscalation: false @@ -25777,7 +25789,7 @@ spec: key: hydrator.enabled name: argocd-cmd-params-cm optional: true - image: quay.io/argoproj/argocd:v2.14.9 + image: quay.io/codefresh/argocd:v2.14.10 imagePullPolicy: Always livenessProbe: httpGet: @@ -26131,7 +26143,7 @@ spec: optional: true - name: KUBECACHEDIR value: /tmp/kubecache - image: quay.io/argoproj/argocd:v2.14.9 + image: quay.io/codefresh/argocd:v2.14.10 imagePullPolicy: Always name: argocd-application-controller ports: diff --git a/manifests/install.yaml b/manifests/install.yaml index f8c1226803f57..56775b6ce06cd 100644 --- a/manifests/install.yaml +++ b/manifests/install.yaml @@ -120,6 +120,12 @@ spec: attempts format: int64 type: integer + changeRevision: + type: string + changeRevisions: + items: + type: string + type: array dryRun: description: DryRun specifies to perform a `kubectl apply --dry-run` without actually performing the sync @@ -2855,6 +2861,12 @@ spec: of auto-heal attempts format: int64 type: integer + changeRevision: + type: string + changeRevisions: + items: + type: string + type: array dryRun: description: DryRun specifies to perform a `kubectl apply --dry-run` without actually performing the sync @@ -24593,7 +24605,7 @@ spec: key: applicationsetcontroller.requeue.after name: argocd-cmd-params-cm optional: true - image: quay.io/argoproj/argocd:v2.14.9 + image: quay.io/codefresh/argocd:v2.14.10 imagePullPolicy: Always name: argocd-applicationset-controller ports: @@ -24730,7 +24742,7 @@ spec: - -n - /usr/local/bin/argocd - /shared/argocd-dex - image: quay.io/argoproj/argocd:v2.14.9 + image: quay.io/codefresh/argocd:v2.14.10 imagePullPolicy: Always name: copyutil securityContext: @@ -24820,7 +24832,7 @@ spec: key: notificationscontroller.repo.server.plaintext name: argocd-cmd-params-cm optional: true - image: quay.io/argoproj/argocd:v2.14.9 + image: quay.io/codefresh/argocd:v2.14.10 imagePullPolicy: Always livenessProbe: tcpSocket: @@ -24922,7 +24934,7 @@ spec: - argocd - admin - redis-initial-password - image: quay.io/argoproj/argocd:v2.14.9 + image: quay.io/codefresh/argocd:v2.14.10 imagePullPolicy: IfNotPresent name: secret-init securityContext: @@ -25183,7 +25195,7 @@ spec: value: /helm-working-dir - name: HELM_DATA_HOME value: /helm-working-dir - image: quay.io/argoproj/argocd:v2.14.9 + image: quay.io/codefresh/argocd:v2.14.10 imagePullPolicy: Always livenessProbe: failureThreshold: 3 @@ -25235,7 +25247,7 @@ spec: - -n - /usr/local/bin/argocd - /var/run/argocd/argocd-cmp-server - image: quay.io/argoproj/argocd:v2.14.9 + image: quay.io/codefresh/argocd:v2.14.10 name: copyutil securityContext: allowPrivilegeEscalation: false @@ -25595,7 +25607,7 @@ spec: key: hydrator.enabled name: argocd-cmd-params-cm optional: true - image: quay.io/argoproj/argocd:v2.14.9 + image: quay.io/codefresh/argocd:v2.14.10 imagePullPolicy: Always livenessProbe: httpGet: @@ -25949,7 +25961,7 @@ spec: optional: true - name: KUBECACHEDIR value: /tmp/kubecache - image: quay.io/argoproj/argocd:v2.14.9 + image: quay.io/codefresh/argocd:v2.14.10 imagePullPolicy: Always name: argocd-application-controller ports: diff --git a/manifests/namespace-install-with-hydrator.yaml b/manifests/namespace-install-with-hydrator.yaml index 34c1cc1d8d5be..ebd7929acf940 100644 --- a/manifests/namespace-install-with-hydrator.yaml +++ b/manifests/namespace-install-with-hydrator.yaml @@ -855,7 +855,7 @@ spec: key: applicationsetcontroller.requeue.after name: argocd-cmd-params-cm optional: true - image: quay.io/argoproj/argocd:v2.14.9 + image: quay.io/codefresh/argocd:v2.14.10 imagePullPolicy: Always name: argocd-applicationset-controller ports: @@ -1142,7 +1142,7 @@ spec: - -n - /usr/local/bin/argocd - /shared/argocd-dex - image: quay.io/argoproj/argocd:v2.14.9 + image: quay.io/codefresh/argocd:v2.14.10 imagePullPolicy: Always name: copyutil securityContext: @@ -1232,7 +1232,7 @@ spec: key: notificationscontroller.repo.server.plaintext name: argocd-cmd-params-cm optional: true - image: quay.io/argoproj/argocd:v2.14.9 + image: quay.io/codefresh/argocd:v2.14.10 imagePullPolicy: Always livenessProbe: tcpSocket: @@ -1334,7 +1334,7 @@ spec: - argocd - admin - redis-initial-password - image: quay.io/argoproj/argocd:v2.14.9 + image: quay.io/codefresh/argocd:v2.14.10 imagePullPolicy: IfNotPresent name: secret-init securityContext: @@ -1595,7 +1595,7 @@ spec: value: /helm-working-dir - name: HELM_DATA_HOME value: /helm-working-dir - image: quay.io/argoproj/argocd:v2.14.9 + image: quay.io/codefresh/argocd:v2.14.10 imagePullPolicy: Always livenessProbe: failureThreshold: 3 @@ -1647,7 +1647,7 @@ spec: - -n - /usr/local/bin/argocd - /var/run/argocd/argocd-cmp-server - image: quay.io/argoproj/argocd:v2.14.9 + image: quay.io/codefresh/argocd:v2.14.10 name: copyutil securityContext: allowPrivilegeEscalation: false @@ -2007,7 +2007,7 @@ spec: key: hydrator.enabled name: argocd-cmd-params-cm optional: true - image: quay.io/argoproj/argocd:v2.14.9 + image: quay.io/codefresh/argocd:v2.14.10 imagePullPolicy: Always livenessProbe: httpGet: @@ -2361,7 +2361,7 @@ spec: optional: true - name: KUBECACHEDIR value: /tmp/kubecache - image: quay.io/argoproj/argocd:v2.14.9 + image: quay.io/codefresh/argocd:v2.14.10 imagePullPolicy: Always name: argocd-application-controller ports: diff --git a/manifests/namespace-install.yaml b/manifests/namespace-install.yaml index 5456ea5762409..a4578b6981966 100644 --- a/manifests/namespace-install.yaml +++ b/manifests/namespace-install.yaml @@ -823,7 +823,7 @@ spec: key: applicationsetcontroller.requeue.after name: argocd-cmd-params-cm optional: true - image: quay.io/argoproj/argocd:v2.14.9 + image: quay.io/codefresh/argocd:v2.14.10 imagePullPolicy: Always name: argocd-applicationset-controller ports: @@ -960,7 +960,7 @@ spec: - -n - /usr/local/bin/argocd - /shared/argocd-dex - image: quay.io/argoproj/argocd:v2.14.9 + image: quay.io/codefresh/argocd:v2.14.10 imagePullPolicy: Always name: copyutil securityContext: @@ -1050,7 +1050,7 @@ spec: key: notificationscontroller.repo.server.plaintext name: argocd-cmd-params-cm optional: true - image: quay.io/argoproj/argocd:v2.14.9 + image: quay.io/codefresh/argocd:v2.14.10 imagePullPolicy: Always livenessProbe: tcpSocket: @@ -1152,7 +1152,7 @@ spec: - argocd - admin - redis-initial-password - image: quay.io/argoproj/argocd:v2.14.9 + image: quay.io/codefresh/argocd:v2.14.10 imagePullPolicy: IfNotPresent name: secret-init securityContext: @@ -1413,7 +1413,7 @@ spec: value: /helm-working-dir - name: HELM_DATA_HOME value: /helm-working-dir - image: quay.io/argoproj/argocd:v2.14.9 + image: quay.io/codefresh/argocd:v2.14.10 imagePullPolicy: Always livenessProbe: failureThreshold: 3 @@ -1465,7 +1465,7 @@ spec: - -n - /usr/local/bin/argocd - /var/run/argocd/argocd-cmp-server - image: quay.io/argoproj/argocd:v2.14.9 + image: quay.io/codefresh/argocd:v2.14.10 name: copyutil securityContext: allowPrivilegeEscalation: false @@ -1825,7 +1825,7 @@ spec: key: hydrator.enabled name: argocd-cmd-params-cm optional: true - image: quay.io/argoproj/argocd:v2.14.9 + image: quay.io/codefresh/argocd:v2.14.10 imagePullPolicy: Always livenessProbe: httpGet: @@ -2179,7 +2179,7 @@ spec: optional: true - name: KUBECACHEDIR value: /tmp/kubecache - image: quay.io/argoproj/argocd:v2.14.9 + image: quay.io/codefresh/argocd:v2.14.10 imagePullPolicy: Always name: argocd-application-controller ports: diff --git a/pkg/apiclient/application/application.pb.go b/pkg/apiclient/application/application.pb.go index 2f73469d1049f..a3fd34497197e 100644 --- a/pkg/apiclient/application/application.pb.go +++ b/pkg/apiclient/application/application.pb.go @@ -594,6 +594,116 @@ func (m *ApplicationManifestQueryWithFiles) GetProject() string { return "" } +type ApplicationValidateResponse struct { + Error *string `protobuf:"bytes,1,opt,name=error" json:"error,omitempty"` + Entity *string `protobuf:"bytes,2,opt,name=entity" json:"entity,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ApplicationValidateResponse) Reset() { *m = ApplicationValidateResponse{} } +func (m *ApplicationValidateResponse) String() string { return proto.CompactTextString(m) } +func (*ApplicationValidateResponse) ProtoMessage() {} +func (*ApplicationValidateResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_df6e82b174b5eaec, []int{7} +} +func (m *ApplicationValidateResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ApplicationValidateResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ApplicationValidateResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *ApplicationValidateResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_ApplicationValidateResponse.Merge(m, src) +} +func (m *ApplicationValidateResponse) XXX_Size() int { + return m.Size() +} +func (m *ApplicationValidateResponse) XXX_DiscardUnknown() { + xxx_messageInfo_ApplicationValidateResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_ApplicationValidateResponse proto.InternalMessageInfo + +func (m *ApplicationValidateResponse) GetError() string { + if m != nil && m.Error != nil { + return *m.Error + } + return "" +} + +func (m *ApplicationValidateResponse) GetEntity() string { + if m != nil && m.Entity != nil { + return *m.Entity + } + return "" +} + +type ApplicationRolloutRollbackResponse struct { + Rollout *string `protobuf:"bytes,1,req,name=rollout" json:"rollout,omitempty"` + NewRevision *int64 `protobuf:"varint,2,req,name=newRevision" json:"newRevision,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ApplicationRolloutRollbackResponse) Reset() { *m = ApplicationRolloutRollbackResponse{} } +func (m *ApplicationRolloutRollbackResponse) String() string { return proto.CompactTextString(m) } +func (*ApplicationRolloutRollbackResponse) ProtoMessage() {} +func (*ApplicationRolloutRollbackResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_df6e82b174b5eaec, []int{8} +} +func (m *ApplicationRolloutRollbackResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ApplicationRolloutRollbackResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ApplicationRolloutRollbackResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *ApplicationRolloutRollbackResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_ApplicationRolloutRollbackResponse.Merge(m, src) +} +func (m *ApplicationRolloutRollbackResponse) XXX_Size() int { + return m.Size() +} +func (m *ApplicationRolloutRollbackResponse) XXX_DiscardUnknown() { + xxx_messageInfo_ApplicationRolloutRollbackResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_ApplicationRolloutRollbackResponse proto.InternalMessageInfo + +func (m *ApplicationRolloutRollbackResponse) GetRollout() string { + if m != nil && m.Rollout != nil { + return *m.Rollout + } + return "" +} + +func (m *ApplicationRolloutRollbackResponse) GetNewRevision() int64 { + if m != nil && m.NewRevision != nil { + return *m.NewRevision + } + return 0 +} + type ApplicationManifestQueryWithFilesWrapper struct { // Types that are valid to be assigned to Part: // *ApplicationManifestQueryWithFilesWrapper_Query @@ -610,7 +720,7 @@ func (m *ApplicationManifestQueryWithFilesWrapper) Reset() { func (m *ApplicationManifestQueryWithFilesWrapper) String() string { return proto.CompactTextString(m) } func (*ApplicationManifestQueryWithFilesWrapper) ProtoMessage() {} func (*ApplicationManifestQueryWithFilesWrapper) Descriptor() ([]byte, []int) { - return fileDescriptor_df6e82b174b5eaec, []int{7} + return fileDescriptor_df6e82b174b5eaec, []int{9} } func (m *ApplicationManifestQueryWithFilesWrapper) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -696,7 +806,7 @@ func (m *ApplicationResponse) Reset() { *m = ApplicationResponse{} } func (m *ApplicationResponse) String() string { return proto.CompactTextString(m) } func (*ApplicationResponse) ProtoMessage() {} func (*ApplicationResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_df6e82b174b5eaec, []int{8} + return fileDescriptor_df6e82b174b5eaec, []int{10} } func (m *ApplicationResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -738,7 +848,7 @@ func (m *ApplicationCreateRequest) Reset() { *m = ApplicationCreateReque func (m *ApplicationCreateRequest) String() string { return proto.CompactTextString(m) } func (*ApplicationCreateRequest) ProtoMessage() {} func (*ApplicationCreateRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_df6e82b174b5eaec, []int{9} + return fileDescriptor_df6e82b174b5eaec, []int{11} } func (m *ApplicationCreateRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -801,7 +911,7 @@ func (m *ApplicationUpdateRequest) Reset() { *m = ApplicationUpdateReque func (m *ApplicationUpdateRequest) String() string { return proto.CompactTextString(m) } func (*ApplicationUpdateRequest) ProtoMessage() {} func (*ApplicationUpdateRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_df6e82b174b5eaec, []int{10} + return fileDescriptor_df6e82b174b5eaec, []int{12} } func (m *ApplicationUpdateRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -866,7 +976,7 @@ func (m *ApplicationDeleteRequest) Reset() { *m = ApplicationDeleteReque func (m *ApplicationDeleteRequest) String() string { return proto.CompactTextString(m) } func (*ApplicationDeleteRequest) ProtoMessage() {} func (*ApplicationDeleteRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_df6e82b174b5eaec, []int{11} + return fileDescriptor_df6e82b174b5eaec, []int{13} } func (m *ApplicationDeleteRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -941,7 +1051,7 @@ func (m *SyncOptions) Reset() { *m = SyncOptions{} } func (m *SyncOptions) String() string { return proto.CompactTextString(m) } func (*SyncOptions) ProtoMessage() {} func (*SyncOptions) Descriptor() ([]byte, []int) { - return fileDescriptor_df6e82b174b5eaec, []int{12} + return fileDescriptor_df6e82b174b5eaec, []int{14} } func (m *SyncOptions) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1002,7 +1112,7 @@ func (m *ApplicationSyncRequest) Reset() { *m = ApplicationSyncRequest{} func (m *ApplicationSyncRequest) String() string { return proto.CompactTextString(m) } func (*ApplicationSyncRequest) ProtoMessage() {} func (*ApplicationSyncRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_df6e82b174b5eaec, []int{13} + return fileDescriptor_df6e82b174b5eaec, []int{15} } func (m *ApplicationSyncRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1129,6 +1239,132 @@ func (m *ApplicationSyncRequest) GetRevisions() []string { return nil } +type ApplicationValidationRequest struct { + Application *v1alpha1.Application `protobuf:"bytes,1,req,name=application" json:"application,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ApplicationValidationRequest) Reset() { *m = ApplicationValidationRequest{} } +func (m *ApplicationValidationRequest) String() string { return proto.CompactTextString(m) } +func (*ApplicationValidationRequest) ProtoMessage() {} +func (*ApplicationValidationRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_df6e82b174b5eaec, []int{16} +} +func (m *ApplicationValidationRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ApplicationValidationRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ApplicationValidationRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *ApplicationValidationRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_ApplicationValidationRequest.Merge(m, src) +} +func (m *ApplicationValidationRequest) XXX_Size() int { + return m.Size() +} +func (m *ApplicationValidationRequest) XXX_DiscardUnknown() { + xxx_messageInfo_ApplicationValidationRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_ApplicationValidationRequest proto.InternalMessageInfo + +func (m *ApplicationValidationRequest) GetApplication() *v1alpha1.Application { + if m != nil { + return m.Application + } + return nil +} + +type ApplicationRolloutRollbackRequest struct { + Name *string `protobuf:"bytes,1,req,name=name" json:"name,omitempty"` + Namespace *string `protobuf:"bytes,2,req,name=namespace" json:"namespace,omitempty"` + RolloutName *string `protobuf:"bytes,3,req,name=rolloutName" json:"rolloutName,omitempty"` + RolloutNamespace *string `protobuf:"bytes,4,req,name=rolloutNamespace" json:"rolloutNamespace,omitempty"` + RolloutRevision *int64 `protobuf:"varint,5,req,name=rolloutRevision" json:"rolloutRevision,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ApplicationRolloutRollbackRequest) Reset() { *m = ApplicationRolloutRollbackRequest{} } +func (m *ApplicationRolloutRollbackRequest) String() string { return proto.CompactTextString(m) } +func (*ApplicationRolloutRollbackRequest) ProtoMessage() {} +func (*ApplicationRolloutRollbackRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_df6e82b174b5eaec, []int{17} +} +func (m *ApplicationRolloutRollbackRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ApplicationRolloutRollbackRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ApplicationRolloutRollbackRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *ApplicationRolloutRollbackRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_ApplicationRolloutRollbackRequest.Merge(m, src) +} +func (m *ApplicationRolloutRollbackRequest) XXX_Size() int { + return m.Size() +} +func (m *ApplicationRolloutRollbackRequest) XXX_DiscardUnknown() { + xxx_messageInfo_ApplicationRolloutRollbackRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_ApplicationRolloutRollbackRequest proto.InternalMessageInfo + +func (m *ApplicationRolloutRollbackRequest) GetName() string { + if m != nil && m.Name != nil { + return *m.Name + } + return "" +} + +func (m *ApplicationRolloutRollbackRequest) GetNamespace() string { + if m != nil && m.Namespace != nil { + return *m.Namespace + } + return "" +} + +func (m *ApplicationRolloutRollbackRequest) GetRolloutName() string { + if m != nil && m.RolloutName != nil { + return *m.RolloutName + } + return "" +} + +func (m *ApplicationRolloutRollbackRequest) GetRolloutNamespace() string { + if m != nil && m.RolloutNamespace != nil { + return *m.RolloutNamespace + } + return "" +} + +func (m *ApplicationRolloutRollbackRequest) GetRolloutRevision() int64 { + if m != nil && m.RolloutRevision != nil { + return *m.RolloutRevision + } + return 0 +} + // ApplicationUpdateSpecRequest is a request to update application spec type ApplicationUpdateSpecRequest struct { Name *string `protobuf:"bytes,1,req,name=name" json:"name,omitempty"` @@ -1145,7 +1381,7 @@ func (m *ApplicationUpdateSpecRequest) Reset() { *m = ApplicationUpdateS func (m *ApplicationUpdateSpecRequest) String() string { return proto.CompactTextString(m) } func (*ApplicationUpdateSpecRequest) ProtoMessage() {} func (*ApplicationUpdateSpecRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_df6e82b174b5eaec, []int{14} + return fileDescriptor_df6e82b174b5eaec, []int{18} } func (m *ApplicationUpdateSpecRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1225,7 +1461,7 @@ func (m *ApplicationPatchRequest) Reset() { *m = ApplicationPatchRequest func (m *ApplicationPatchRequest) String() string { return proto.CompactTextString(m) } func (*ApplicationPatchRequest) ProtoMessage() {} func (*ApplicationPatchRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_df6e82b174b5eaec, []int{15} + return fileDescriptor_df6e82b174b5eaec, []int{19} } func (m *ApplicationPatchRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1305,7 +1541,7 @@ func (m *ApplicationRollbackRequest) Reset() { *m = ApplicationRollbackR func (m *ApplicationRollbackRequest) String() string { return proto.CompactTextString(m) } func (*ApplicationRollbackRequest) ProtoMessage() {} func (*ApplicationRollbackRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_df6e82b174b5eaec, []int{16} + return fileDescriptor_df6e82b174b5eaec, []int{20} } func (m *ApplicationRollbackRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1394,7 +1630,7 @@ func (m *ApplicationResourceRequest) Reset() { *m = ApplicationResourceR func (m *ApplicationResourceRequest) String() string { return proto.CompactTextString(m) } func (*ApplicationResourceRequest) ProtoMessage() {} func (*ApplicationResourceRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_df6e82b174b5eaec, []int{17} + return fileDescriptor_df6e82b174b5eaec, []int{21} } func (m *ApplicationResourceRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1479,6 +1715,124 @@ func (m *ApplicationResourceRequest) GetProject() string { return "" } +type ChangeRevisionRequest struct { + AppName *string `protobuf:"bytes,1,req,name=appName" json:"appName,omitempty"` + Namespace *string `protobuf:"bytes,2,opt,name=namespace" json:"namespace,omitempty"` + CurrentRevision *string `protobuf:"bytes,3,opt,name=currentRevision" json:"currentRevision,omitempty"` + PreviousRevision *string `protobuf:"bytes,4,opt,name=previousRevision" json:"previousRevision,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ChangeRevisionRequest) Reset() { *m = ChangeRevisionRequest{} } +func (m *ChangeRevisionRequest) String() string { return proto.CompactTextString(m) } +func (*ChangeRevisionRequest) ProtoMessage() {} +func (*ChangeRevisionRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_df6e82b174b5eaec, []int{22} +} +func (m *ChangeRevisionRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ChangeRevisionRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ChangeRevisionRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *ChangeRevisionRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_ChangeRevisionRequest.Merge(m, src) +} +func (m *ChangeRevisionRequest) XXX_Size() int { + return m.Size() +} +func (m *ChangeRevisionRequest) XXX_DiscardUnknown() { + xxx_messageInfo_ChangeRevisionRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_ChangeRevisionRequest proto.InternalMessageInfo + +func (m *ChangeRevisionRequest) GetAppName() string { + if m != nil && m.AppName != nil { + return *m.AppName + } + return "" +} + +func (m *ChangeRevisionRequest) GetNamespace() string { + if m != nil && m.Namespace != nil { + return *m.Namespace + } + return "" +} + +func (m *ChangeRevisionRequest) GetCurrentRevision() string { + if m != nil && m.CurrentRevision != nil { + return *m.CurrentRevision + } + return "" +} + +func (m *ChangeRevisionRequest) GetPreviousRevision() string { + if m != nil && m.PreviousRevision != nil { + return *m.PreviousRevision + } + return "" +} + +type ChangeRevisionResponse struct { + Revision *string `protobuf:"bytes,1,req,name=revision" json:"revision,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ChangeRevisionResponse) Reset() { *m = ChangeRevisionResponse{} } +func (m *ChangeRevisionResponse) String() string { return proto.CompactTextString(m) } +func (*ChangeRevisionResponse) ProtoMessage() {} +func (*ChangeRevisionResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_df6e82b174b5eaec, []int{23} +} +func (m *ChangeRevisionResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ChangeRevisionResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ChangeRevisionResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *ChangeRevisionResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_ChangeRevisionResponse.Merge(m, src) +} +func (m *ChangeRevisionResponse) XXX_Size() int { + return m.Size() +} +func (m *ChangeRevisionResponse) XXX_DiscardUnknown() { + xxx_messageInfo_ChangeRevisionResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_ChangeRevisionResponse proto.InternalMessageInfo + +func (m *ChangeRevisionResponse) GetRevision() string { + if m != nil && m.Revision != nil { + return *m.Revision + } + return "" +} + type ApplicationResourcePatchRequest struct { Name *string `protobuf:"bytes,1,req,name=name" json:"name,omitempty"` Namespace *string `protobuf:"bytes,2,opt,name=namespace" json:"namespace,omitempty"` @@ -1499,7 +1853,7 @@ func (m *ApplicationResourcePatchRequest) Reset() { *m = ApplicationReso func (m *ApplicationResourcePatchRequest) String() string { return proto.CompactTextString(m) } func (*ApplicationResourcePatchRequest) ProtoMessage() {} func (*ApplicationResourcePatchRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_df6e82b174b5eaec, []int{18} + return fileDescriptor_df6e82b174b5eaec, []int{24} } func (m *ApplicationResourcePatchRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1618,7 +1972,7 @@ func (m *ApplicationResourceDeleteRequest) Reset() { *m = ApplicationRes func (m *ApplicationResourceDeleteRequest) String() string { return proto.CompactTextString(m) } func (*ApplicationResourceDeleteRequest) ProtoMessage() {} func (*ApplicationResourceDeleteRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_df6e82b174b5eaec, []int{19} + return fileDescriptor_df6e82b174b5eaec, []int{25} } func (m *ApplicationResourceDeleteRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1736,7 +2090,7 @@ func (m *ResourceActionRunRequest) Reset() { *m = ResourceActionRunReque func (m *ResourceActionRunRequest) String() string { return proto.CompactTextString(m) } func (*ResourceActionRunRequest) ProtoMessage() {} func (*ResourceActionRunRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_df6e82b174b5eaec, []int{20} + return fileDescriptor_df6e82b174b5eaec, []int{26} } func (m *ResourceActionRunRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1839,7 +2193,7 @@ func (m *ResourceActionsListResponse) Reset() { *m = ResourceActionsList func (m *ResourceActionsListResponse) String() string { return proto.CompactTextString(m) } func (*ResourceActionsListResponse) ProtoMessage() {} func (*ResourceActionsListResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_df6e82b174b5eaec, []int{21} + return fileDescriptor_df6e82b174b5eaec, []int{27} } func (m *ResourceActionsListResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1886,7 +2240,7 @@ func (m *ApplicationResourceResponse) Reset() { *m = ApplicationResource func (m *ApplicationResourceResponse) String() string { return proto.CompactTextString(m) } func (*ApplicationResourceResponse) ProtoMessage() {} func (*ApplicationResourceResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_df6e82b174b5eaec, []int{22} + return fileDescriptor_df6e82b174b5eaec, []int{28} } func (m *ApplicationResourceResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1948,7 +2302,7 @@ func (m *ApplicationPodLogsQuery) Reset() { *m = ApplicationPodLogsQuery func (m *ApplicationPodLogsQuery) String() string { return proto.CompactTextString(m) } func (*ApplicationPodLogsQuery) ProtoMessage() {} func (*ApplicationPodLogsQuery) Descriptor() ([]byte, []int) { - return fileDescriptor_df6e82b174b5eaec, []int{23} + return fileDescriptor_df6e82b174b5eaec, []int{29} } func (m *ApplicationPodLogsQuery) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2105,7 +2459,7 @@ func (m *LogEntry) Reset() { *m = LogEntry{} } func (m *LogEntry) String() string { return proto.CompactTextString(m) } func (*LogEntry) ProtoMessage() {} func (*LogEntry) Descriptor() ([]byte, []int) { - return fileDescriptor_df6e82b174b5eaec, []int{24} + return fileDescriptor_df6e82b174b5eaec, []int{30} } func (m *LogEntry) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2182,7 +2536,7 @@ func (m *OperationTerminateRequest) Reset() { *m = OperationTerminateReq func (m *OperationTerminateRequest) String() string { return proto.CompactTextString(m) } func (*OperationTerminateRequest) ProtoMessage() {} func (*OperationTerminateRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_df6e82b174b5eaec, []int{25} + return fileDescriptor_df6e82b174b5eaec, []int{31} } func (m *OperationTerminateRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2245,7 +2599,7 @@ func (m *ApplicationSyncWindowsQuery) Reset() { *m = ApplicationSyncWind func (m *ApplicationSyncWindowsQuery) String() string { return proto.CompactTextString(m) } func (*ApplicationSyncWindowsQuery) ProtoMessage() {} func (*ApplicationSyncWindowsQuery) Descriptor() ([]byte, []int) { - return fileDescriptor_df6e82b174b5eaec, []int{26} + return fileDescriptor_df6e82b174b5eaec, []int{32} } func (m *ApplicationSyncWindowsQuery) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2308,7 +2662,7 @@ func (m *ApplicationSyncWindowsResponse) Reset() { *m = ApplicationSyncW func (m *ApplicationSyncWindowsResponse) String() string { return proto.CompactTextString(m) } func (*ApplicationSyncWindowsResponse) ProtoMessage() {} func (*ApplicationSyncWindowsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_df6e82b174b5eaec, []int{27} + return fileDescriptor_df6e82b174b5eaec, []int{33} } func (m *ApplicationSyncWindowsResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2372,7 +2726,7 @@ func (m *ApplicationSyncWindow) Reset() { *m = ApplicationSyncWindow{} } func (m *ApplicationSyncWindow) String() string { return proto.CompactTextString(m) } func (*ApplicationSyncWindow) ProtoMessage() {} func (*ApplicationSyncWindow) Descriptor() ([]byte, []int) { - return fileDescriptor_df6e82b174b5eaec, []int{28} + return fileDescriptor_df6e82b174b5eaec, []int{34} } func (m *ApplicationSyncWindow) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2439,7 +2793,7 @@ func (m *OperationTerminateResponse) Reset() { *m = OperationTerminateRe func (m *OperationTerminateResponse) String() string { return proto.CompactTextString(m) } func (*OperationTerminateResponse) ProtoMessage() {} func (*OperationTerminateResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_df6e82b174b5eaec, []int{29} + return fileDescriptor_df6e82b174b5eaec, []int{35} } func (m *OperationTerminateResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2486,7 +2840,7 @@ func (m *ResourcesQuery) Reset() { *m = ResourcesQuery{} } func (m *ResourcesQuery) String() string { return proto.CompactTextString(m) } func (*ResourcesQuery) ProtoMessage() {} func (*ResourcesQuery) Descriptor() ([]byte, []int) { - return fileDescriptor_df6e82b174b5eaec, []int{30} + return fileDescriptor_df6e82b174b5eaec, []int{36} } func (m *ResourcesQuery) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2582,7 +2936,7 @@ func (m *ManagedResourcesResponse) Reset() { *m = ManagedResourcesRespon func (m *ManagedResourcesResponse) String() string { return proto.CompactTextString(m) } func (*ManagedResourcesResponse) ProtoMessage() {} func (*ManagedResourcesResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_df6e82b174b5eaec, []int{31} + return fileDescriptor_df6e82b174b5eaec, []int{37} } func (m *ManagedResourcesResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2632,7 +2986,7 @@ func (m *LinkInfo) Reset() { *m = LinkInfo{} } func (m *LinkInfo) String() string { return proto.CompactTextString(m) } func (*LinkInfo) ProtoMessage() {} func (*LinkInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_df6e82b174b5eaec, []int{32} + return fileDescriptor_df6e82b174b5eaec, []int{38} } func (m *LinkInfo) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2700,7 +3054,7 @@ func (m *LinksResponse) Reset() { *m = LinksResponse{} } func (m *LinksResponse) String() string { return proto.CompactTextString(m) } func (*LinksResponse) ProtoMessage() {} func (*LinksResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_df6e82b174b5eaec, []int{33} + return fileDescriptor_df6e82b174b5eaec, []int{39} } func (m *LinksResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2749,7 +3103,7 @@ func (m *ListAppLinksRequest) Reset() { *m = ListAppLinksRequest{} } func (m *ListAppLinksRequest) String() string { return proto.CompactTextString(m) } func (*ListAppLinksRequest) ProtoMessage() {} func (*ListAppLinksRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_df6e82b174b5eaec, []int{34} + return fileDescriptor_df6e82b174b5eaec, []int{40} } func (m *ListAppLinksRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2807,6 +3161,8 @@ func init() { proto.RegisterType((*ApplicationManifestQuery)(nil), "application.ApplicationManifestQuery") proto.RegisterType((*FileChunk)(nil), "application.FileChunk") proto.RegisterType((*ApplicationManifestQueryWithFiles)(nil), "application.ApplicationManifestQueryWithFiles") + proto.RegisterType((*ApplicationValidateResponse)(nil), "application.ApplicationValidateResponse") + proto.RegisterType((*ApplicationRolloutRollbackResponse)(nil), "application.ApplicationRolloutRollbackResponse") proto.RegisterType((*ApplicationManifestQueryWithFilesWrapper)(nil), "application.ApplicationManifestQueryWithFilesWrapper") proto.RegisterType((*ApplicationResponse)(nil), "application.ApplicationResponse") proto.RegisterType((*ApplicationCreateRequest)(nil), "application.ApplicationCreateRequest") @@ -2814,10 +3170,14 @@ func init() { proto.RegisterType((*ApplicationDeleteRequest)(nil), "application.ApplicationDeleteRequest") proto.RegisterType((*SyncOptions)(nil), "application.SyncOptions") proto.RegisterType((*ApplicationSyncRequest)(nil), "application.ApplicationSyncRequest") + proto.RegisterType((*ApplicationValidationRequest)(nil), "application.ApplicationValidationRequest") + proto.RegisterType((*ApplicationRolloutRollbackRequest)(nil), "application.ApplicationRolloutRollbackRequest") proto.RegisterType((*ApplicationUpdateSpecRequest)(nil), "application.ApplicationUpdateSpecRequest") proto.RegisterType((*ApplicationPatchRequest)(nil), "application.ApplicationPatchRequest") proto.RegisterType((*ApplicationRollbackRequest)(nil), "application.ApplicationRollbackRequest") proto.RegisterType((*ApplicationResourceRequest)(nil), "application.ApplicationResourceRequest") + proto.RegisterType((*ChangeRevisionRequest)(nil), "application.ChangeRevisionRequest") + proto.RegisterType((*ChangeRevisionResponse)(nil), "application.ChangeRevisionResponse") proto.RegisterType((*ApplicationResourcePatchRequest)(nil), "application.ApplicationResourcePatchRequest") proto.RegisterType((*ApplicationResourceDeleteRequest)(nil), "application.ApplicationResourceDeleteRequest") proto.RegisterType((*ResourceActionRunRequest)(nil), "application.ResourceActionRunRequest") @@ -2842,179 +3202,197 @@ func init() { } var fileDescriptor_df6e82b174b5eaec = []byte{ - // 2742 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x5a, 0x4d, 0x8c, 0x1b, 0x49, - 0x15, 0xa6, 0xec, 0xf1, 0x8c, 0xe7, 0x79, 0x26, 0x93, 0xd4, 0x26, 0x83, 0xd7, 0x99, 0x0d, 0xde, - 0x4e, 0xb2, 0x71, 0x26, 0x19, 0x3b, 0x31, 0x01, 0x65, 0x67, 0x77, 0x05, 0xc9, 0xe4, 0x17, 0x26, - 0xd9, 0xd0, 0x93, 0x10, 0xb4, 0x1c, 0xa0, 0xb6, 0xbb, 0xc6, 0xd3, 0x4c, 0xbb, 0xbb, 0xd3, 0xdd, - 0x76, 0x18, 0x85, 0x5c, 0x16, 0xed, 0x05, 0xad, 0x40, 0xc0, 0x1e, 0x10, 0x42, 0x80, 0x16, 0xad, - 0x84, 0x10, 0x88, 0x0b, 0x42, 0x48, 0x08, 0x09, 0x0e, 0x20, 0x38, 0x20, 0xad, 0xe0, 0xc8, 0x05, - 0x45, 0x88, 0x23, 0x5c, 0xf6, 0x8c, 0x50, 0x55, 0x57, 0x75, 0x57, 0xfb, 0xa7, 0xed, 0xc1, 0x46, - 0x9b, 0x5b, 0xbf, 0x72, 0xd5, 0x7b, 0xdf, 0x7b, 0xf5, 0xea, 0xbd, 0x57, 0xaf, 0x0c, 0x27, 0x02, - 0xea, 0x77, 0xa9, 0xdf, 0x20, 0x9e, 0x67, 0x5b, 0x06, 0x09, 0x2d, 0xd7, 0x51, 0xbf, 0xeb, 0x9e, - 0xef, 0x86, 0x2e, 0x2e, 0x29, 0x43, 0x95, 0x95, 0x96, 0xeb, 0xb6, 0x6c, 0xda, 0x20, 0x9e, 0xd5, - 0x20, 0x8e, 0xe3, 0x86, 0x7c, 0x38, 0x88, 0xa6, 0x56, 0xb4, 0xdd, 0x8b, 0x41, 0xdd, 0x72, 0xf9, - 0xaf, 0x86, 0xeb, 0xd3, 0x46, 0xf7, 0x7c, 0xa3, 0x45, 0x1d, 0xea, 0x93, 0x90, 0x9a, 0x62, 0xce, - 0x85, 0x64, 0x4e, 0x9b, 0x18, 0x3b, 0x96, 0x43, 0xfd, 0xbd, 0x86, 0xb7, 0xdb, 0x62, 0x03, 0x41, - 0xa3, 0x4d, 0x43, 0x32, 0x68, 0xd5, 0x66, 0xcb, 0x0a, 0x77, 0x3a, 0xaf, 0xd7, 0x0d, 0xb7, 0xdd, - 0x20, 0x7e, 0xcb, 0xf5, 0x7c, 0xf7, 0x4b, 0xfc, 0x63, 0xcd, 0x30, 0x1b, 0xdd, 0x66, 0xc2, 0x40, - 0xd5, 0xa5, 0x7b, 0x9e, 0xd8, 0xde, 0x0e, 0xe9, 0xe7, 0x76, 0x75, 0x04, 0x37, 0x9f, 0x7a, 0xae, - 0xb0, 0x0d, 0xff, 0xb4, 0x42, 0xd7, 0xdf, 0x53, 0x3e, 0x23, 0x36, 0xda, 0xfb, 0x08, 0x0e, 0x5e, - 0x4a, 0xe4, 0x7d, 0xa6, 0x43, 0xfd, 0x3d, 0x8c, 0x61, 0xc6, 0x21, 0x6d, 0x5a, 0x46, 0x55, 0x54, - 0x9b, 0xd7, 0xf9, 0x37, 0x2e, 0xc3, 0x9c, 0x4f, 0xb7, 0x7d, 0x1a, 0xec, 0x94, 0x73, 0x7c, 0x58, - 0x92, 0xb8, 0x02, 0x45, 0x26, 0x9c, 0x1a, 0x61, 0x50, 0xce, 0x57, 0xf3, 0xb5, 0x79, 0x3d, 0xa6, - 0x71, 0x0d, 0x96, 0x7c, 0x1a, 0xb8, 0x1d, 0xdf, 0xa0, 0x9f, 0xa5, 0x7e, 0x60, 0xb9, 0x4e, 0x79, - 0x86, 0xaf, 0xee, 0x1d, 0x66, 0x5c, 0x02, 0x6a, 0x53, 0x23, 0x74, 0xfd, 0x72, 0x81, 0x4f, 0x89, - 0x69, 0x86, 0x87, 0x01, 0x2f, 0xcf, 0x46, 0x78, 0xd8, 0x37, 0xd6, 0x60, 0x81, 0x78, 0xde, 0x6d, - 0xd2, 0xa6, 0x81, 0x47, 0x0c, 0x5a, 0x9e, 0xe3, 0xbf, 0xa5, 0xc6, 0x18, 0x66, 0x81, 0xa4, 0x5c, - 0xe4, 0xc0, 0x24, 0xa9, 0x6d, 0xc0, 0xfc, 0x6d, 0xd7, 0xa4, 0xc3, 0xd5, 0xed, 0x65, 0x9f, 0xeb, - 0x67, 0xaf, 0xfd, 0x1e, 0xc1, 0x11, 0x9d, 0x76, 0x2d, 0x86, 0xff, 0x16, 0x0d, 0x89, 0x49, 0x42, - 0xd2, 0xcb, 0x31, 0x17, 0x73, 0xac, 0x40, 0xd1, 0x17, 0x93, 0xcb, 0x39, 0x3e, 0x1e, 0xd3, 0x7d, - 0xd2, 0xf2, 0xd9, 0xca, 0x44, 0x26, 0x94, 0x24, 0xae, 0x42, 0x29, 0xb2, 0xe5, 0x4d, 0xc7, 0xa4, - 0x5f, 0xe6, 0xd6, 0x2b, 0xe8, 0xea, 0x10, 0x5e, 0x81, 0xf9, 0x6e, 0x64, 0xe7, 0x9b, 0x26, 0xb7, - 0x62, 0x41, 0x4f, 0x06, 0xb4, 0x7f, 0x22, 0x38, 0xa6, 0xf8, 0x80, 0x2e, 0x76, 0xe6, 0x6a, 0x97, - 0x3a, 0x61, 0x30, 0x5c, 0xa1, 0xb3, 0x70, 0x48, 0x6e, 0x62, 0xaf, 0x9d, 0xfa, 0x7f, 0x60, 0x2a, - 0xaa, 0x83, 0x52, 0x45, 0x75, 0x8c, 0x29, 0x22, 0xe9, 0x7b, 0x37, 0xaf, 0x08, 0x35, 0xd5, 0xa1, - 0x3e, 0x43, 0x15, 0xb2, 0x0d, 0x35, 0x9b, 0x32, 0x94, 0xf6, 0x1e, 0x82, 0xb2, 0xa2, 0xe8, 0x2d, - 0xe2, 0x58, 0xdb, 0x34, 0x08, 0xc7, 0xdd, 0x33, 0x34, 0xc5, 0x3d, 0xab, 0xc1, 0x52, 0xa4, 0xd5, - 0x1d, 0x76, 0x1e, 0x59, 0xfc, 0x29, 0x17, 0xaa, 0xf9, 0x5a, 0x5e, 0xef, 0x1d, 0x66, 0x7b, 0x27, - 0x65, 0x06, 0xe5, 0x59, 0xee, 0xc6, 0xc9, 0x80, 0xf6, 0x3c, 0xcc, 0x5f, 0xb3, 0x6c, 0xba, 0xb1, - 0xd3, 0x71, 0x76, 0xf1, 0x61, 0x28, 0x18, 0xec, 0x83, 0xeb, 0xb0, 0xa0, 0x47, 0x84, 0xf6, 0x4d, - 0x04, 0xcf, 0x0f, 0xd3, 0xfa, 0xbe, 0x15, 0xee, 0xb0, 0xf5, 0xc1, 0x30, 0xf5, 0x8d, 0x1d, 0x6a, - 0xec, 0x06, 0x9d, 0xb6, 0x74, 0x59, 0x49, 0x4f, 0xa6, 0xbe, 0xf6, 0x13, 0x04, 0xb5, 0x91, 0x98, - 0xee, 0xfb, 0xc4, 0xf3, 0xa8, 0x8f, 0xaf, 0x41, 0xe1, 0x01, 0xfb, 0x81, 0x1f, 0xd0, 0x52, 0xb3, - 0x5e, 0x57, 0x03, 0xfc, 0x48, 0x2e, 0x37, 0x3e, 0xa4, 0x47, 0xcb, 0x71, 0x5d, 0x9a, 0x27, 0xc7, - 0xf9, 0x2c, 0xa7, 0xf8, 0xc4, 0x56, 0x64, 0xf3, 0xf9, 0xb4, 0xcb, 0xb3, 0x30, 0xe3, 0x11, 0x3f, - 0xd4, 0x8e, 0xc0, 0x33, 0xe9, 0xe3, 0xe1, 0xb9, 0x4e, 0x40, 0xb5, 0x5f, 0xa7, 0xbd, 0x69, 0xc3, - 0xa7, 0x24, 0xa4, 0x3a, 0x7d, 0xd0, 0xa1, 0x41, 0x88, 0x77, 0x41, 0xcd, 0x39, 0xdc, 0xaa, 0xa5, - 0xe6, 0xcd, 0x7a, 0x12, 0xb4, 0xeb, 0x32, 0x68, 0xf3, 0x8f, 0x2f, 0x18, 0x66, 0xbd, 0xdb, 0xac, - 0x7b, 0xbb, 0xad, 0x3a, 0x4b, 0x01, 0x29, 0x64, 0x32, 0x05, 0xa8, 0xaa, 0xea, 0x2a, 0x77, 0xbc, - 0x0c, 0xb3, 0x1d, 0x2f, 0xa0, 0x7e, 0xc8, 0x35, 0x2b, 0xea, 0x82, 0x62, 0xfb, 0xd7, 0x25, 0xb6, - 0x65, 0x92, 0x30, 0xda, 0x9f, 0xa2, 0x1e, 0xd3, 0xda, 0x6f, 0xd2, 0xe8, 0xef, 0x79, 0xe6, 0x07, - 0x85, 0x5e, 0x45, 0x99, 0x4b, 0xa3, 0x54, 0x3d, 0x28, 0x9f, 0xf6, 0xa0, 0x5f, 0xa4, 0xf1, 0x5f, - 0xa1, 0x36, 0x4d, 0xf0, 0x0f, 0x72, 0xe6, 0x32, 0xcc, 0x19, 0x24, 0x30, 0x88, 0x29, 0xa5, 0x48, - 0x92, 0x05, 0x32, 0xcf, 0x77, 0x3d, 0xd2, 0xe2, 0x9c, 0xee, 0xb8, 0xb6, 0x65, 0xec, 0x09, 0x71, - 0xfd, 0x3f, 0xf4, 0x39, 0xfe, 0x4c, 0xb6, 0xe3, 0x17, 0xd2, 0xb0, 0x8f, 0x43, 0x69, 0x6b, 0xcf, - 0x31, 0x5e, 0xf5, 0xa2, 0xc3, 0x7d, 0x18, 0x0a, 0x56, 0x48, 0xdb, 0x41, 0x19, 0xf1, 0x83, 0x1d, - 0x11, 0xda, 0x7f, 0x0a, 0xb0, 0xac, 0xe8, 0xc6, 0x16, 0x64, 0x69, 0x96, 0x15, 0xa5, 0x96, 0x61, - 0xd6, 0xf4, 0xf7, 0xf4, 0x8e, 0x23, 0x1c, 0x40, 0x50, 0x4c, 0xb0, 0xe7, 0x77, 0x9c, 0x08, 0x7e, - 0x51, 0x8f, 0x08, 0xbc, 0x0d, 0xc5, 0x20, 0x64, 0x55, 0x46, 0x6b, 0x8f, 0x03, 0x2f, 0x35, 0x3f, - 0x35, 0xd9, 0xa6, 0x33, 0xe8, 0x5b, 0x82, 0xa3, 0x1e, 0xf3, 0xc6, 0x0f, 0x58, 0x4c, 0x8b, 0x02, - 0x5d, 0x50, 0x9e, 0xab, 0xe6, 0x6b, 0xa5, 0xe6, 0xd6, 0xe4, 0x82, 0x5e, 0xf5, 0x58, 0x85, 0xa4, - 0x64, 0x30, 0x3d, 0x91, 0xc2, 0xc2, 0x68, 0x5b, 0xc4, 0x87, 0x40, 0x54, 0x03, 0xc9, 0x00, 0xfe, - 0x1c, 0x14, 0x2c, 0x67, 0xdb, 0x0d, 0xca, 0xf3, 0x1c, 0xcc, 0xe5, 0xc9, 0xc0, 0xdc, 0x74, 0xb6, - 0x5d, 0x3d, 0x62, 0x88, 0x1f, 0xc0, 0xa2, 0x4f, 0x43, 0x7f, 0x4f, 0x5a, 0xa1, 0x0c, 0xdc, 0xae, - 0x9f, 0x9e, 0x4c, 0x82, 0xae, 0xb2, 0xd4, 0xd3, 0x12, 0xf0, 0x3a, 0x94, 0x82, 0xc4, 0xc7, 0xca, - 0x25, 0x2e, 0xb0, 0x9c, 0x62, 0xa4, 0xf8, 0xa0, 0xae, 0x4e, 0xee, 0xf3, 0xee, 0x85, 0x6c, 0xef, - 0x5e, 0x1c, 0x99, 0xd5, 0x0e, 0x8c, 0x91, 0xd5, 0x96, 0x7a, 0xb3, 0xda, 0xbf, 0x11, 0xac, 0xf4, - 0x05, 0xa7, 0x2d, 0x8f, 0x66, 0x1e, 0x03, 0x02, 0x33, 0x81, 0x47, 0x0d, 0x9e, 0xa9, 0x4a, 0xcd, - 0x5b, 0x53, 0x8b, 0x56, 0x5c, 0x2e, 0x67, 0x9d, 0x15, 0x50, 0x27, 0x8c, 0x0b, 0x3f, 0x40, 0xf0, - 0x61, 0x45, 0xe6, 0x1d, 0x12, 0x1a, 0x3b, 0x59, 0xca, 0xb2, 0xf3, 0xcb, 0xe6, 0x88, 0xbc, 0x1c, - 0x11, 0xcc, 0xaa, 0xfc, 0xe3, 0xee, 0x9e, 0xc7, 0x00, 0xb2, 0x5f, 0x92, 0x81, 0x09, 0x8b, 0xa7, - 0x9f, 0x22, 0xa8, 0xa8, 0x31, 0xdc, 0xb5, 0xed, 0xd7, 0x89, 0xb1, 0x9b, 0x05, 0xf2, 0x00, 0xe4, - 0x2c, 0x93, 0x23, 0xcc, 0xeb, 0x39, 0xcb, 0xdc, 0x67, 0x30, 0xea, 0x85, 0x3b, 0x9b, 0x0d, 0x77, - 0x2e, 0x0d, 0xf7, 0xfd, 0x1e, 0xb8, 0x32, 0x24, 0x64, 0xc0, 0x5d, 0x81, 0x79, 0xa7, 0xa7, 0x90, - 0x4d, 0x06, 0x06, 0x14, 0xb0, 0xb9, 0xbe, 0x02, 0xb6, 0x0c, 0x73, 0xdd, 0xf8, 0x9a, 0xc3, 0x7e, - 0x96, 0x24, 0x53, 0xb1, 0xe5, 0xbb, 0x1d, 0x4f, 0x18, 0x3d, 0x22, 0x18, 0x8a, 0x5d, 0xcb, 0x61, - 0x25, 0x39, 0x47, 0xc1, 0xbe, 0xf7, 0x7f, 0xb1, 0x49, 0xa9, 0xfd, 0xb3, 0x1c, 0x7c, 0x64, 0x80, - 0xda, 0x23, 0xfd, 0xe9, 0xe9, 0xd0, 0x3d, 0xf6, 0xea, 0xb9, 0xa1, 0x5e, 0x5d, 0x1c, 0xe5, 0xd5, - 0xf3, 0xd9, 0xf6, 0x82, 0xb4, 0xbd, 0x7e, 0x9c, 0x83, 0xea, 0x00, 0x7b, 0x8d, 0x2e, 0x27, 0x9e, - 0x1a, 0x83, 0x6d, 0xbb, 0xbe, 0xf0, 0x92, 0xa2, 0x1e, 0x11, 0xec, 0x9c, 0xb9, 0xbe, 0xb7, 0x43, - 0x1c, 0xee, 0x1d, 0x45, 0x5d, 0x50, 0x13, 0x9a, 0xea, 0x6b, 0x39, 0x28, 0x4b, 0xfb, 0x5c, 0x32, - 0xb8, 0xb5, 0x3a, 0xce, 0xd3, 0x6f, 0xa2, 0x65, 0x98, 0x25, 0x1c, 0xad, 0x70, 0x2a, 0x41, 0xf5, - 0x19, 0xa3, 0x98, 0x6d, 0x8c, 0xf9, 0xb4, 0x31, 0xde, 0x44, 0x70, 0x34, 0x6d, 0x8c, 0x60, 0xd3, - 0x0a, 0x42, 0x79, 0x39, 0xc0, 0xdb, 0x30, 0x17, 0xc9, 0x89, 0x4a, 0xbb, 0x52, 0x73, 0x73, 0xd2, - 0x84, 0x9f, 0x32, 0xbc, 0x64, 0xae, 0xbd, 0x08, 0x47, 0x07, 0x46, 0x39, 0x01, 0xa3, 0x02, 0x45, - 0x59, 0xe4, 0x88, 0xad, 0x89, 0x69, 0xed, 0xcd, 0x99, 0x74, 0xca, 0x71, 0xcd, 0x4d, 0xb7, 0x95, - 0x71, 0xdf, 0xcf, 0xde, 0x4e, 0x66, 0x2a, 0xd7, 0x54, 0xae, 0xf6, 0x92, 0x64, 0xeb, 0x0c, 0xd7, - 0x09, 0x89, 0xe5, 0x50, 0x5f, 0x64, 0xc5, 0x64, 0x80, 0x6d, 0x43, 0x60, 0x39, 0x06, 0xdd, 0xa2, - 0x86, 0xeb, 0x98, 0x01, 0xdf, 0xcf, 0xbc, 0x9e, 0x1a, 0xc3, 0x37, 0x60, 0x9e, 0xd3, 0x77, 0xad, - 0x76, 0x94, 0x06, 0x4a, 0xcd, 0xd5, 0x7a, 0xd4, 0x83, 0xab, 0xab, 0x3d, 0xb8, 0xc4, 0x86, 0x6d, - 0x1a, 0x92, 0x7a, 0xf7, 0x7c, 0x9d, 0xad, 0xd0, 0x93, 0xc5, 0x0c, 0x4b, 0x48, 0x2c, 0x7b, 0xd3, - 0x72, 0x78, 0xe1, 0xc9, 0x44, 0x25, 0x03, 0xcc, 0x55, 0xb6, 0x5d, 0xdb, 0x76, 0x1f, 0xca, 0x73, - 0x13, 0x51, 0x6c, 0x55, 0xc7, 0x09, 0x2d, 0x9b, 0xcb, 0x8f, 0x1c, 0x21, 0x19, 0xe0, 0xab, 0x2c, - 0x3b, 0xa4, 0xbe, 0x38, 0x30, 0x82, 0x8a, 0x9d, 0xb1, 0x14, 0xb5, 0x95, 0xe4, 0x79, 0x8d, 0xdc, - 0x76, 0x41, 0x75, 0xdb, 0xde, 0xa3, 0xb0, 0x38, 0xa0, 0x37, 0xc2, 0xbb, 0x6c, 0xb4, 0x6b, 0xb9, - 0x1d, 0x56, 0x53, 0xf1, 0xd2, 0x43, 0xd2, 0x7d, 0xae, 0xbc, 0x94, 0xed, 0xca, 0x07, 0xd3, 0xae, - 0xfc, 0x5b, 0x04, 0xc5, 0x4d, 0xb7, 0x75, 0xd5, 0x09, 0xfd, 0x3d, 0x7e, 0x4b, 0x72, 0x9d, 0x90, - 0x3a, 0xd2, 0x5f, 0x24, 0xc9, 0x36, 0x21, 0xb4, 0xda, 0x74, 0x2b, 0x24, 0x6d, 0x4f, 0xd4, 0x58, - 0xfb, 0xda, 0x84, 0x78, 0x31, 0x33, 0x8c, 0x4d, 0x82, 0x90, 0x9f, 0xf8, 0xa2, 0xce, 0xbf, 0x99, - 0x0a, 0xf1, 0x84, 0xad, 0xd0, 0x17, 0xc7, 0x3d, 0x35, 0xa6, 0xba, 0x58, 0x21, 0xc2, 0x26, 0x48, - 0xad, 0x0d, 0xcf, 0xc6, 0xc5, 0xff, 0x5d, 0xea, 0xb7, 0x2d, 0x87, 0x64, 0x47, 0xef, 0x31, 0xda, - 0x7b, 0x19, 0x77, 0x4f, 0x37, 0x75, 0xe8, 0x58, 0x2d, 0x7d, 0xdf, 0x72, 0x4c, 0xf7, 0x61, 0xc6, - 0xe1, 0x99, 0x4c, 0xe0, 0x5f, 0xd2, 0x1d, 0x3a, 0x45, 0x62, 0x7c, 0xd2, 0x6f, 0xc0, 0x22, 0x8b, - 0x09, 0x5d, 0x2a, 0x7e, 0x10, 0x61, 0x47, 0x1b, 0xd6, 0x2c, 0x49, 0x78, 0xe8, 0xe9, 0x85, 0x78, - 0x13, 0x96, 0x48, 0x10, 0x58, 0x2d, 0x87, 0x9a, 0x92, 0x57, 0x6e, 0x6c, 0x5e, 0xbd, 0x4b, 0xa3, - 0x6b, 0x37, 0x9f, 0x21, 0xf6, 0x5b, 0x92, 0xda, 0x57, 0x11, 0x1c, 0x19, 0xc8, 0x24, 0x3e, 0x39, - 0x48, 0x09, 0xe3, 0x15, 0x28, 0x06, 0xc6, 0x0e, 0x35, 0x3b, 0x36, 0x95, 0xbd, 0x28, 0x49, 0xb3, - 0xdf, 0xcc, 0x4e, 0xb4, 0xfb, 0x22, 0x8d, 0xc4, 0x34, 0x3e, 0x06, 0xd0, 0x26, 0x4e, 0x87, 0xd8, - 0x1c, 0xc2, 0x0c, 0x87, 0xa0, 0x8c, 0x68, 0x2b, 0x50, 0x19, 0xe4, 0x3a, 0xa2, 0xc7, 0xf3, 0x2f, - 0x04, 0x07, 0x64, 0x50, 0x15, 0xbb, 0x5b, 0x83, 0x25, 0xc5, 0x0c, 0xb7, 0x93, 0x8d, 0xee, 0x1d, - 0x1e, 0x11, 0x30, 0xa5, 0x97, 0xe4, 0xd3, 0x4d, 0xf6, 0x6e, 0xaa, 0x4d, 0x3e, 0x76, 0xbe, 0x43, - 0x53, 0xaa, 0x1f, 0xbf, 0x02, 0xe5, 0x5b, 0xc4, 0x21, 0x2d, 0x6a, 0xc6, 0x6a, 0xc7, 0x2e, 0xf6, - 0x45, 0xb5, 0x59, 0x31, 0x71, 0x6b, 0x20, 0x2e, 0xb5, 0xac, 0xed, 0x6d, 0xd9, 0xf8, 0xf0, 0xa1, - 0xb8, 0x69, 0x39, 0xbb, 0xec, 0xfe, 0xcc, 0x34, 0x0e, 0xad, 0xd0, 0x96, 0xd6, 0x8d, 0x08, 0x7c, - 0x10, 0xf2, 0x1d, 0xdf, 0x16, 0x1e, 0xc0, 0x3e, 0x71, 0x15, 0x4a, 0x26, 0x0d, 0x0c, 0xdf, 0xf2, - 0xc4, 0xfe, 0xf3, 0xa6, 0xb1, 0x32, 0xc4, 0xf6, 0xc1, 0x32, 0x5c, 0x67, 0xc3, 0x26, 0x41, 0x20, - 0x13, 0x50, 0x3c, 0xa0, 0xbd, 0x0c, 0x8b, 0x4c, 0x66, 0xa2, 0xe6, 0x99, 0xb4, 0x9a, 0x47, 0x52, - 0xf0, 0x25, 0x3c, 0x89, 0x98, 0xc0, 0x33, 0x2c, 0xef, 0x5f, 0xf2, 0x3c, 0xc1, 0x64, 0xcc, 0x72, - 0x28, 0x3f, 0x28, 0x7f, 0x0e, 0xec, 0x95, 0x36, 0xff, 0x76, 0x1c, 0xb0, 0x7a, 0x4e, 0xa8, 0xdf, - 0xb5, 0x0c, 0x8a, 0xbf, 0x85, 0x60, 0x86, 0x89, 0xc6, 0xcf, 0x0d, 0x3b, 0x96, 0xdc, 0x5f, 0x2b, - 0xd3, 0xbb, 0x08, 0x33, 0x69, 0xda, 0xca, 0x1b, 0x7f, 0xfd, 0xc7, 0xb7, 0x73, 0xcb, 0xf8, 0x30, - 0x7f, 0x21, 0xeb, 0x9e, 0x57, 0x5f, 0xab, 0x02, 0xfc, 0x16, 0x02, 0x2c, 0xea, 0x20, 0xe5, 0x0d, - 0x01, 0x9f, 0x19, 0x06, 0x71, 0xc0, 0x5b, 0x43, 0xe5, 0x39, 0x25, 0xab, 0xd4, 0x0d, 0xd7, 0xa7, - 0x2c, 0x87, 0xf0, 0x09, 0x1c, 0xc0, 0x2a, 0x07, 0x70, 0x02, 0x6b, 0x83, 0x00, 0x34, 0x1e, 0x31, - 0x8b, 0x3e, 0x6e, 0xd0, 0x48, 0xee, 0x3b, 0x08, 0x0a, 0xf7, 0xf9, 0x1d, 0x62, 0x84, 0x91, 0xb6, - 0xa6, 0x66, 0x24, 0x2e, 0x8e, 0xa3, 0xd5, 0x8e, 0x73, 0xa4, 0xcf, 0xe1, 0xa3, 0x12, 0x69, 0x10, - 0xfa, 0x94, 0xb4, 0x53, 0x80, 0xcf, 0x21, 0xfc, 0x2e, 0x82, 0xd9, 0xa8, 0x79, 0x8c, 0x4f, 0x0e, - 0x43, 0x99, 0x6a, 0x2e, 0x57, 0xa6, 0xd7, 0x89, 0xd5, 0x4e, 0x73, 0x8c, 0xc7, 0xb5, 0x81, 0xdb, - 0xb9, 0x9e, 0xea, 0xd3, 0xbe, 0x8d, 0x20, 0x7f, 0x9d, 0x8e, 0xf4, 0xb7, 0x29, 0x82, 0xeb, 0x33, - 0xe0, 0x80, 0xad, 0xc6, 0x3f, 0x42, 0xf0, 0xec, 0x75, 0x1a, 0x0e, 0x4e, 0x8f, 0xb8, 0x36, 0x3a, - 0x67, 0x09, 0xb7, 0x3b, 0x33, 0xc6, 0xcc, 0x38, 0x2f, 0x34, 0x38, 0xb2, 0xd3, 0xf8, 0x54, 0x96, - 0x13, 0x06, 0x7b, 0x8e, 0xf1, 0x50, 0xe0, 0xf8, 0x13, 0x82, 0x83, 0xbd, 0x6f, 0x85, 0x38, 0x9d, - 0x50, 0x07, 0x3e, 0x25, 0x56, 0x6e, 0x4f, 0x1a, 0x65, 0xd3, 0x4c, 0xb5, 0x4b, 0x1c, 0xf9, 0x4b, - 0xf8, 0xc5, 0x2c, 0xe4, 0x71, 0x27, 0xae, 0xf1, 0x48, 0x7e, 0x3e, 0xe6, 0xef, 0xda, 0x1c, 0xf6, - 0x9f, 0x11, 0x1c, 0x96, 0x7c, 0x37, 0x76, 0x88, 0x1f, 0x5e, 0xa1, 0xac, 0x86, 0x0e, 0xc6, 0xd2, - 0x67, 0xc2, 0xac, 0xa1, 0xca, 0xd3, 0xae, 0x72, 0x5d, 0x3e, 0x81, 0x5f, 0xd9, 0xb7, 0x2e, 0x06, - 0x63, 0x63, 0x0a, 0xd8, 0x6f, 0x20, 0x58, 0xb8, 0x4e, 0xc3, 0x5b, 0x71, 0x37, 0xf8, 0xe4, 0x58, - 0x2f, 0x4c, 0x95, 0x95, 0xba, 0xf2, 0x9c, 0x2e, 0x7f, 0x8a, 0x5d, 0x64, 0x8d, 0x83, 0x3b, 0x85, - 0x4f, 0x66, 0x81, 0x4b, 0x3a, 0xd0, 0xef, 0x20, 0x38, 0xa2, 0x82, 0x48, 0x5e, 0xe6, 0x3e, 0xb6, - 0xbf, 0xf7, 0x2e, 0xf1, 0x6a, 0x36, 0x02, 0x5d, 0x93, 0xa3, 0x3b, 0xab, 0x0d, 0x76, 0xe0, 0x76, - 0x1f, 0x8a, 0x75, 0xb4, 0x5a, 0x43, 0xf8, 0x77, 0x08, 0x66, 0xa3, 0x66, 0xec, 0x70, 0x1b, 0xa5, - 0x5e, 0x92, 0xa6, 0x19, 0x0d, 0xc4, 0x6e, 0x57, 0xce, 0x0d, 0x36, 0xa8, 0xba, 0x5e, 0xba, 0x6a, - 0x9d, 0x5b, 0x39, 0x1d, 0xc6, 0x7e, 0x89, 0x00, 0x92, 0x86, 0x32, 0x3e, 0x9d, 0xad, 0x87, 0xd2, - 0x74, 0xae, 0x4c, 0xb7, 0xa5, 0xac, 0xd5, 0xb9, 0x3e, 0xb5, 0x4a, 0x35, 0x33, 0x86, 0x78, 0xd4, - 0x58, 0x8f, 0x9a, 0xcf, 0x3f, 0x44, 0x50, 0xe0, 0x7d, 0x3c, 0x7c, 0x62, 0x18, 0x66, 0xb5, 0xcd, - 0x37, 0x4d, 0xd3, 0xbf, 0xc0, 0xa1, 0x56, 0x9b, 0x59, 0x81, 0x78, 0x1d, 0xad, 0xe2, 0x2e, 0xcc, - 0x46, 0x9d, 0xb3, 0xe1, 0xee, 0x91, 0xea, 0xac, 0x55, 0xaa, 0x19, 0x85, 0x41, 0xe4, 0xa8, 0x22, - 0x07, 0xac, 0x8e, 0xca, 0x01, 0x33, 0x2c, 0x4c, 0xe3, 0xe3, 0x59, 0x41, 0xfc, 0xff, 0x60, 0x98, - 0x33, 0x1c, 0xdd, 0x49, 0xad, 0x3a, 0x2a, 0x0f, 0x30, 0xeb, 0x7c, 0x07, 0xc1, 0xc1, 0xde, 0xe2, - 0x1a, 0x1f, 0xed, 0x89, 0x99, 0xea, 0x5d, 0xa3, 0x92, 0xb6, 0xe2, 0xb0, 0xc2, 0x5c, 0xfb, 0x24, - 0x47, 0xb1, 0x8e, 0x2f, 0x8e, 0x3c, 0x19, 0xb7, 0x65, 0xd4, 0x61, 0x8c, 0xd6, 0x92, 0xd7, 0xb1, - 0x5f, 0x21, 0x58, 0x90, 0x7c, 0xef, 0xfa, 0x94, 0x66, 0xc3, 0x9a, 0xde, 0x41, 0x60, 0xb2, 0xb4, - 0x97, 0x39, 0xfc, 0x8f, 0xe3, 0x0b, 0x63, 0xc2, 0x97, 0xb0, 0xd7, 0x42, 0x86, 0xf4, 0x0f, 0x08, - 0x0e, 0xdd, 0x8f, 0xfc, 0xfe, 0x03, 0xc2, 0xbf, 0xc1, 0xf1, 0xbf, 0x82, 0x5f, 0xca, 0xa8, 0xf3, - 0x46, 0xa9, 0x71, 0x0e, 0xe1, 0x9f, 0x23, 0x28, 0xca, 0x57, 0x15, 0x7c, 0x6a, 0xe8, 0xc1, 0x48, - 0xbf, 0xbb, 0x4c, 0xd3, 0x99, 0x45, 0x51, 0xa3, 0x9d, 0xc8, 0x4c, 0xa7, 0x42, 0x3e, 0x73, 0xe8, - 0xb7, 0x11, 0xe0, 0xf8, 0xce, 0x1c, 0xdf, 0xa2, 0xf1, 0x0b, 0x29, 0x51, 0x43, 0x1b, 0x33, 0x95, - 0x53, 0x23, 0xe7, 0xa5, 0x53, 0xe9, 0x6a, 0x66, 0x2a, 0x75, 0x63, 0xf9, 0x5f, 0x47, 0x50, 0xba, - 0x4e, 0xe3, 0x3b, 0x48, 0x86, 0x2d, 0xd3, 0x8f, 0x42, 0x95, 0xda, 0xe8, 0x89, 0x02, 0xd1, 0x59, - 0x8e, 0xe8, 0x05, 0x9c, 0x6d, 0x2a, 0x09, 0xe0, 0x7b, 0x08, 0x16, 0xef, 0xa8, 0x2e, 0x8a, 0xcf, - 0x8e, 0x92, 0x94, 0x8a, 0xe4, 0xe3, 0xe3, 0xfa, 0x28, 0xc7, 0xb5, 0xa6, 0x8d, 0x85, 0x6b, 0x5d, - 0xbc, 0xaf, 0x7c, 0x1f, 0x45, 0x97, 0xd8, 0x9e, 0x7e, 0xf6, 0xff, 0x6a, 0xb7, 0x8c, 0xb6, 0xb8, - 0x76, 0x81, 0xe3, 0xab, 0xe3, 0xb3, 0xe3, 0xe0, 0x6b, 0x88, 0x26, 0x37, 0xfe, 0x2e, 0x82, 0x43, - 0xfc, 0xad, 0x41, 0x65, 0xdc, 0x93, 0x62, 0x86, 0xbd, 0x4c, 0x8c, 0x91, 0x62, 0x44, 0xfc, 0xd1, - 0xf6, 0x05, 0x6a, 0x5d, 0xbe, 0x23, 0x7c, 0x03, 0xc1, 0x01, 0x99, 0xd4, 0xc4, 0xee, 0xae, 0x8d, - 0x32, 0xdc, 0x7e, 0x93, 0xa0, 0x70, 0xb7, 0xd5, 0xf1, 0xdc, 0xed, 0x5d, 0x04, 0x73, 0xa2, 0x9b, - 0x9f, 0x51, 0x2a, 0x28, 0xed, 0xfe, 0x4a, 0x4f, 0x8f, 0x43, 0x34, 0x83, 0xb5, 0xcf, 0x73, 0xb1, - 0xf7, 0x70, 0x23, 0x4b, 0xac, 0xe7, 0x9a, 0x41, 0xe3, 0x91, 0xe8, 0xc4, 0x3e, 0x6e, 0xd8, 0x6e, - 0x2b, 0x78, 0x4d, 0xc3, 0x99, 0x09, 0x91, 0xcd, 0x39, 0x87, 0x70, 0x08, 0xf3, 0xcc, 0x39, 0x78, - 0xe3, 0x04, 0x57, 0x7b, 0xda, 0x2c, 0x7d, 0x3d, 0x95, 0x4a, 0xa5, 0xaf, 0x11, 0x93, 0x64, 0x40, - 0x71, 0x8d, 0xc5, 0xcf, 0x67, 0x8a, 0xe5, 0x82, 0xde, 0x42, 0x70, 0x48, 0xf5, 0xf6, 0x48, 0xfc, - 0xd8, 0xbe, 0x9e, 0x85, 0x42, 0x14, 0xd5, 0x78, 0x75, 0x2c, 0x47, 0xe2, 0x70, 0x2e, 0x5f, 0xfb, - 0xe3, 0x93, 0x63, 0xe8, 0xbd, 0x27, 0xc7, 0xd0, 0xdf, 0x9f, 0x1c, 0x43, 0xaf, 0x5d, 0x1c, 0xef, - 0x3f, 0xc2, 0x86, 0x6d, 0x51, 0x27, 0x54, 0xd9, 0xff, 0x37, 0x00, 0x00, 0xff, 0xff, 0x45, 0x63, - 0x3b, 0x00, 0x09, 0x2d, 0x00, 0x00, + // 3034 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x5b, 0xcd, 0x8f, 0x1c, 0x47, + 0x15, 0xa7, 0x66, 0x77, 0x76, 0x67, 0xdf, 0xd8, 0x5e, 0xbb, 0x62, 0x2f, 0x9d, 0xf6, 0xc6, 0x6c, + 0xda, 0x76, 0x3c, 0x59, 0x7b, 0x67, 0xec, 0xc5, 0x40, 0xb2, 0x49, 0x04, 0xce, 0xda, 0x71, 0x4c, + 0xd6, 0x8e, 0xe9, 0x75, 0x62, 0x14, 0x0e, 0xa4, 0xd3, 0x5d, 0x3b, 0xdb, 0xec, 0x4c, 0x77, 0xbb, + 0xba, 0x67, 0xcc, 0x2a, 0xe4, 0x12, 0x14, 0x09, 0x41, 0x04, 0x02, 0x72, 0x40, 0x80, 0x00, 0x05, + 0x45, 0x42, 0x08, 0xc4, 0x05, 0x45, 0x48, 0x28, 0x12, 0x1c, 0x40, 0x70, 0x88, 0x14, 0xc1, 0x3f, + 0x80, 0x22, 0xc4, 0x11, 0x2e, 0x39, 0x23, 0x54, 0xd5, 0x55, 0xdd, 0x55, 0xf3, 0xd1, 0x33, 0xcb, + 0x2c, 0xc4, 0xa7, 0xed, 0x57, 0x5d, 0xfd, 0xea, 0xf7, 0x5e, 0xbd, 0xaf, 0x7a, 0x35, 0x0b, 0xa7, + 0x62, 0x42, 0xbb, 0x84, 0x36, 0x9c, 0x28, 0x6a, 0xf9, 0xae, 0x93, 0xf8, 0x61, 0xa0, 0x3e, 0xd7, + 0x23, 0x1a, 0x26, 0x21, 0xae, 0x2a, 0x43, 0xe6, 0x62, 0x33, 0x0c, 0x9b, 0x2d, 0xd2, 0x70, 0x22, + 0xbf, 0xe1, 0x04, 0x41, 0x98, 0xf0, 0xe1, 0x38, 0x9d, 0x6a, 0x5a, 0x3b, 0x8f, 0xc4, 0x75, 0x3f, + 0xe4, 0x6f, 0xdd, 0x90, 0x92, 0x46, 0xf7, 0x42, 0xa3, 0x49, 0x02, 0x42, 0x9d, 0x84, 0x78, 0x62, + 0xce, 0xc5, 0x7c, 0x4e, 0xdb, 0x71, 0xb7, 0xfd, 0x80, 0xd0, 0xdd, 0x46, 0xb4, 0xd3, 0x64, 0x03, + 0x71, 0xa3, 0x4d, 0x12, 0x67, 0xd0, 0x57, 0x1b, 0x4d, 0x3f, 0xd9, 0xee, 0xbc, 0x54, 0x77, 0xc3, + 0x76, 0xc3, 0xa1, 0xcd, 0x30, 0xa2, 0xe1, 0x97, 0xf8, 0xc3, 0x8a, 0xeb, 0x35, 0xba, 0xab, 0x39, + 0x03, 0x55, 0x96, 0xee, 0x05, 0xa7, 0x15, 0x6d, 0x3b, 0xfd, 0xdc, 0xae, 0x8c, 0xe0, 0x46, 0x49, + 0x14, 0x0a, 0xdd, 0xf0, 0x47, 0x3f, 0x09, 0xe9, 0xae, 0xf2, 0x98, 0xb2, 0xb1, 0x3e, 0x40, 0x70, + 0xf8, 0x52, 0xbe, 0xde, 0xe7, 0x3a, 0x84, 0xee, 0x62, 0x0c, 0xd3, 0x81, 0xd3, 0x26, 0x06, 0x5a, + 0x42, 0xb5, 0x39, 0x9b, 0x3f, 0x63, 0x03, 0x66, 0x29, 0xd9, 0xa2, 0x24, 0xde, 0x36, 0x4a, 0x7c, + 0x58, 0x92, 0xd8, 0x84, 0x0a, 0x5b, 0x9c, 0xb8, 0x49, 0x6c, 0x4c, 0x2d, 0x4d, 0xd5, 0xe6, 0xec, + 0x8c, 0xc6, 0x35, 0x98, 0xa7, 0x24, 0x0e, 0x3b, 0xd4, 0x25, 0xcf, 0x13, 0x1a, 0xfb, 0x61, 0x60, + 0x4c, 0xf3, 0xaf, 0x7b, 0x87, 0x19, 0x97, 0x98, 0xb4, 0x88, 0x9b, 0x84, 0xd4, 0x28, 0xf3, 0x29, + 0x19, 0xcd, 0xf0, 0x30, 0xe0, 0xc6, 0x4c, 0x8a, 0x87, 0x3d, 0x63, 0x0b, 0x0e, 0x38, 0x51, 0x74, + 0xc3, 0x69, 0x93, 0x38, 0x72, 0x5c, 0x62, 0xcc, 0xf2, 0x77, 0xda, 0x18, 0xc3, 0x2c, 0x90, 0x18, + 0x15, 0x0e, 0x4c, 0x92, 0xd6, 0x3a, 0xcc, 0xdd, 0x08, 0x3d, 0x32, 0x5c, 0xdc, 0x5e, 0xf6, 0xa5, + 0x7e, 0xf6, 0xd6, 0x1f, 0x10, 0x1c, 0xb3, 0x49, 0xd7, 0x67, 0xf8, 0xaf, 0x93, 0xc4, 0xf1, 0x9c, + 0xc4, 0xe9, 0xe5, 0x58, 0xca, 0x38, 0x9a, 0x50, 0xa1, 0x62, 0xb2, 0x51, 0xe2, 0xe3, 0x19, 0xdd, + 0xb7, 0xda, 0x54, 0xb1, 0x30, 0xa9, 0x0a, 0x25, 0x89, 0x97, 0xa0, 0x9a, 0xea, 0xf2, 0x5a, 0xe0, + 0x91, 0x2f, 0x73, 0xed, 0x95, 0x6d, 0x75, 0x08, 0x2f, 0xc2, 0x5c, 0x37, 0xd5, 0xf3, 0x35, 0x8f, + 0x6b, 0xb1, 0x6c, 0xe7, 0x03, 0xd6, 0x3f, 0x10, 0x9c, 0x50, 0x6c, 0xc0, 0x16, 0x3b, 0x73, 0xa5, + 0x4b, 0x82, 0x24, 0x1e, 0x2e, 0xd0, 0x39, 0x38, 0x22, 0x37, 0xb1, 0x57, 0x4f, 0xfd, 0x2f, 0x98, + 0x88, 0xea, 0xa0, 0x14, 0x51, 0x1d, 0x63, 0x82, 0x48, 0xfa, 0xb9, 0x6b, 0x97, 0x85, 0x98, 0xea, + 0x50, 0x9f, 0xa2, 0xca, 0xc5, 0x8a, 0x9a, 0xd1, 0x14, 0x65, 0xbd, 0x87, 0xc0, 0x50, 0x04, 0xbd, + 0xee, 0x04, 0xfe, 0x16, 0x89, 0x93, 0x71, 0xf7, 0x0c, 0xed, 0xe3, 0x9e, 0xd5, 0x60, 0x3e, 0x95, + 0xea, 0x26, 0xf3, 0x47, 0x16, 0x7f, 0x8c, 0xf2, 0xd2, 0x54, 0x6d, 0xca, 0xee, 0x1d, 0x66, 0x7b, + 0x27, 0xd7, 0x8c, 0x8d, 0x19, 0x6e, 0xc6, 0xf9, 0x80, 0xf5, 0x20, 0xcc, 0x3d, 0xe5, 0xb7, 0xc8, + 0xfa, 0x76, 0x27, 0xd8, 0xc1, 0x47, 0xa1, 0xec, 0xb2, 0x07, 0x2e, 0xc3, 0x01, 0x3b, 0x25, 0xac, + 0x6f, 0x23, 0x78, 0x70, 0x98, 0xd4, 0xb7, 0xfd, 0x64, 0x9b, 0x7d, 0x1f, 0x0f, 0x13, 0xdf, 0xdd, + 0x26, 0xee, 0x4e, 0xdc, 0x69, 0x4b, 0x93, 0x95, 0xf4, 0x64, 0xe2, 0x5b, 0xcf, 0xc0, 0x71, 0x05, + 0xd2, 0xf3, 0x4e, 0xcb, 0xf7, 0x9c, 0x84, 0xd8, 0x24, 0x8e, 0xc2, 0x20, 0x26, 0x4c, 0x10, 0x42, + 0x69, 0x48, 0x85, 0x4b, 0xa6, 0x04, 0x5e, 0x80, 0x19, 0x12, 0x24, 0x7e, 0xb2, 0x2b, 0xf6, 0x42, + 0x50, 0xd6, 0x8b, 0x60, 0xa9, 0xe6, 0x1b, 0xb6, 0x5a, 0x61, 0x27, 0x61, 0x7f, 0x5e, 0x72, 0xdc, + 0x9d, 0x8c, 0x27, 0x0b, 0x60, 0xe9, 0x2b, 0x21, 0xa3, 0x24, 0x99, 0xd9, 0x05, 0xe4, 0xae, 0xad, + 0x3a, 0xe7, 0x94, 0xad, 0x0e, 0x59, 0x3f, 0x47, 0x50, 0x1b, 0xa9, 0xc2, 0xdb, 0xd4, 0x89, 0x22, + 0x42, 0xf1, 0x53, 0x50, 0xbe, 0xc3, 0x5e, 0x70, 0xf0, 0xd5, 0xd5, 0x7a, 0x5d, 0xcd, 0x47, 0x23, + 0xb9, 0x3c, 0xfd, 0x11, 0x3b, 0xfd, 0x1c, 0xd7, 0xe5, 0x6e, 0x96, 0x38, 0x9f, 0x05, 0x8d, 0x4f, + 0xb6, 0xe9, 0x6c, 0x3e, 0x9f, 0xf6, 0xe4, 0x0c, 0x4c, 0x47, 0x0e, 0x4d, 0xac, 0x63, 0x70, 0x9f, + 0xee, 0xcd, 0x5c, 0x7e, 0xeb, 0xb7, 0xba, 0xf1, 0xaf, 0x53, 0xc2, 0x35, 0x7e, 0xa7, 0x43, 0xe2, + 0x04, 0xef, 0x80, 0x9a, 0x22, 0xb9, 0x82, 0xaa, 0xab, 0xd7, 0xea, 0x79, 0x8e, 0xa9, 0xcb, 0x1c, + 0xc3, 0x1f, 0xbe, 0xe8, 0x7a, 0xf5, 0xee, 0x6a, 0x3d, 0xda, 0x69, 0xd6, 0x59, 0xc6, 0xd2, 0x90, + 0xc9, 0x8c, 0xa5, 0x8a, 0x6a, 0xab, 0xdc, 0xd9, 0x3e, 0x76, 0xa2, 0x98, 0xd0, 0x84, 0x4b, 0x56, + 0xb1, 0x05, 0xc5, 0xcc, 0xad, 0x2b, 0x2c, 0x81, 0x9b, 0x53, 0xc5, 0xce, 0x68, 0xeb, 0x1d, 0x1d, + 0xfd, 0x73, 0x91, 0xf7, 0x61, 0xa1, 0x57, 0x51, 0x96, 0x74, 0x94, 0xaa, 0xc1, 0x4f, 0xe9, 0x06, + 0xff, 0x6b, 0x1d, 0xff, 0x65, 0xd2, 0x22, 0x39, 0xfe, 0x41, 0xbe, 0x67, 0xc0, 0xac, 0xeb, 0xc4, + 0xae, 0xe3, 0xc9, 0x55, 0x24, 0xc9, 0xe2, 0x6e, 0x44, 0xc3, 0xc8, 0x69, 0x72, 0x4e, 0x37, 0xc3, + 0x96, 0xef, 0xee, 0x8a, 0xe5, 0xfa, 0x5f, 0xf4, 0xf9, 0xe9, 0x74, 0xb1, 0x9f, 0x96, 0x75, 0xd8, + 0x27, 0xa1, 0xba, 0xb9, 0x1b, 0xb8, 0xcf, 0x46, 0x69, 0x2c, 0x3a, 0x0a, 0x65, 0x3f, 0x21, 0xed, + 0xd8, 0x40, 0x3c, 0x0e, 0xa5, 0x84, 0xf5, 0xef, 0x32, 0x2c, 0x28, 0xb2, 0xb1, 0x0f, 0x8a, 0x24, + 0x2b, 0x0a, 0xaa, 0x0b, 0x30, 0xe3, 0xd1, 0x5d, 0xbb, 0x13, 0x08, 0x03, 0x10, 0x14, 0x5b, 0x38, + 0xa2, 0x9d, 0x20, 0x85, 0x5f, 0xb1, 0x53, 0x02, 0x6f, 0x41, 0x25, 0x4e, 0x58, 0x51, 0xd4, 0xdc, + 0xe5, 0xc0, 0xab, 0xab, 0x9f, 0x9d, 0x6c, 0xd3, 0x19, 0xf4, 0x4d, 0xc1, 0xd1, 0xce, 0x78, 0xe3, + 0x3b, 0x2c, 0x04, 0xa7, 0x71, 0x39, 0x36, 0x66, 0x97, 0xa6, 0x6a, 0xd5, 0xd5, 0xcd, 0xc9, 0x17, + 0x7a, 0x36, 0x62, 0x05, 0x9d, 0x92, 0x70, 0xed, 0x7c, 0x15, 0x16, 0xf5, 0xdb, 0x22, 0x3e, 0xc4, + 0xa2, 0x78, 0xc9, 0x07, 0xf0, 0xe7, 0xa1, 0xec, 0x07, 0x5b, 0x61, 0x6c, 0xcc, 0x71, 0x30, 0x4f, + 0x4e, 0x06, 0xe6, 0x5a, 0xb0, 0x15, 0xda, 0x29, 0x43, 0x7c, 0x07, 0x0e, 0x52, 0x92, 0xd0, 0x5d, + 0xa9, 0x05, 0x03, 0xb8, 0x5e, 0x9f, 0x99, 0x6c, 0x05, 0x5b, 0x65, 0x69, 0xeb, 0x2b, 0xe0, 0x35, + 0xa8, 0xc6, 0xb9, 0x8d, 0x19, 0x55, 0xbe, 0xa0, 0xa1, 0x31, 0x52, 0x6c, 0xd0, 0x56, 0x27, 0xf7, + 0x59, 0xf7, 0x81, 0x62, 0xeb, 0x3e, 0x38, 0x32, 0x09, 0x1f, 0x1a, 0x23, 0x09, 0xcf, 0xf7, 0x26, + 0xe1, 0x6f, 0x20, 0x58, 0xec, 0x4f, 0x67, 0x7c, 0x67, 0xff, 0xff, 0x01, 0xca, 0x7a, 0x57, 0xcf, + 0xf7, 0x7d, 0xf9, 0x70, 0xb8, 0x67, 0x2e, 0xc2, 0x5c, 0xa0, 0x54, 0x72, 0xec, 0x45, 0x3e, 0xc0, + 0xab, 0xb3, 0x94, 0x97, 0x28, 0xe0, 0x4a, 0xbc, 0x3a, 0xcb, 0x87, 0xf0, 0x32, 0x1c, 0x56, 0x48, + 0x19, 0x6f, 0xd8, 0xb4, 0xbe, 0x71, 0x7e, 0x32, 0x10, 0xc8, 0x64, 0x30, 0x28, 0xf3, 0xc4, 0xdb, + 0x3b, 0x6c, 0xfd, 0x4b, 0xd7, 0x6e, 0x1a, 0xfa, 0x37, 0x23, 0x52, 0x18, 0x64, 0x1c, 0x98, 0x8e, + 0x23, 0xe2, 0x72, 0x29, 0xaa, 0xab, 0xd7, 0xf7, 0x4d, 0xd5, 0x7c, 0x5d, 0xce, 0xba, 0x28, 0x5d, + 0x4d, 0x18, 0x75, 0x7f, 0x8c, 0xe0, 0xa3, 0xca, 0x9a, 0x37, 0x9d, 0xc4, 0xdd, 0x2e, 0x12, 0x96, + 0x45, 0x47, 0x36, 0x47, 0xec, 0x59, 0x4a, 0xb0, 0xdd, 0xe4, 0x0f, 0xb7, 0x76, 0x23, 0xb9, 0x5b, + 0xf9, 0xc0, 0x84, 0x95, 0xf4, 0x2f, 0x10, 0x98, 0x3d, 0x36, 0x36, 0xca, 0xb8, 0x0e, 0x41, 0xc9, + 0xf7, 0x44, 0x71, 0x55, 0xf2, 0xbd, 0x3d, 0x86, 0xfa, 0x5e, 0xb8, 0x33, 0xc5, 0x70, 0x67, 0x75, + 0xb8, 0x1f, 0xf4, 0xc0, 0x95, 0x01, 0x77, 0x7c, 0x5f, 0x40, 0xba, 0x2f, 0xf4, 0x9f, 0x66, 0x4a, + 0x7d, 0xa7, 0x19, 0x03, 0x66, 0xbb, 0xd9, 0x99, 0x97, 0x17, 0x9c, 0x82, 0x64, 0x22, 0x36, 0x69, + 0xd8, 0x89, 0x84, 0xd2, 0x53, 0x82, 0xa1, 0xd8, 0xf1, 0x03, 0x76, 0x3e, 0xe3, 0x28, 0xd8, 0xf3, + 0xde, 0x4f, 0xb9, 0x9a, 0xd8, 0x6f, 0x21, 0x38, 0xb6, 0xbe, 0xed, 0x04, 0x4d, 0x22, 0x9d, 0x49, + 0x4a, 0x6c, 0xc0, 0xac, 0xe0, 0x21, 0x8b, 0x61, 0x41, 0x8e, 0x90, 0xbb, 0x06, 0xf3, 0x6e, 0x87, + 0x52, 0x12, 0xe4, 0x5e, 0x9b, 0x56, 0x1e, 0xbd, 0xc3, 0x2c, 0x16, 0x44, 0x2c, 0x42, 0x86, 0x9d, + 0x38, 0x9b, 0x9a, 0x7a, 0x41, 0xdf, 0xb8, 0x75, 0x11, 0x16, 0x7a, 0x61, 0x8a, 0xa2, 0x5d, 0xad, + 0x15, 0x90, 0x7e, 0x68, 0xb6, 0x7e, 0x59, 0x82, 0x8f, 0x0d, 0xd8, 0xd4, 0x91, 0xde, 0x72, 0x6f, + 0xec, 0x6c, 0xe6, 0xb3, 0xb3, 0x43, 0x7d, 0xb6, 0x32, 0xca, 0x67, 0xe7, 0x8a, 0xad, 0x01, 0x74, + 0x6b, 0xf8, 0x59, 0x09, 0x96, 0x06, 0xe8, 0x6b, 0x74, 0x29, 0x7a, 0xcf, 0x28, 0x6c, 0x2b, 0xa4, + 0xc2, 0x07, 0x2a, 0x76, 0x4a, 0xb0, 0x28, 0x12, 0xd2, 0x68, 0xdb, 0x09, 0xb8, 0xed, 0x57, 0x6c, + 0x41, 0x4d, 0xa8, 0xaa, 0xaf, 0x97, 0xc0, 0x90, 0xfa, 0xb9, 0xe4, 0x72, 0x6d, 0x75, 0x82, 0x7b, + 0x5f, 0x45, 0x0b, 0x30, 0xe3, 0x70, 0xb4, 0xc2, 0xa8, 0x04, 0xd5, 0xa7, 0x8c, 0x4a, 0xb1, 0x32, + 0xe6, 0x74, 0x65, 0xbc, 0x86, 0xe0, 0xb8, 0xae, 0x8c, 0x78, 0xc3, 0x8f, 0x93, 0xcc, 0x47, 0xb7, + 0x60, 0x36, 0x5d, 0x27, 0x3d, 0x16, 0x54, 0x57, 0x37, 0x26, 0x2d, 0x16, 0x35, 0xc5, 0x4b, 0xe6, + 0xd6, 0xa3, 0x5a, 0xcf, 0x20, 0x8f, 0xe1, 0x79, 0xa8, 0x90, 0x05, 0xb2, 0x0c, 0x15, 0x92, 0xb6, + 0x5e, 0x9b, 0xd6, 0x13, 0x6a, 0xe8, 0x6d, 0x84, 0xcd, 0x82, 0xd6, 0x56, 0xf1, 0x76, 0x32, 0x55, + 0x85, 0x9e, 0xd2, 0xc5, 0x92, 0x24, 0xfb, 0xce, 0x0d, 0x83, 0xc4, 0xf1, 0x03, 0x42, 0x45, 0xb4, + 0xcb, 0x07, 0xd8, 0x36, 0xc4, 0x7e, 0xe0, 0x92, 0x4d, 0xe2, 0x86, 0x81, 0x17, 0xf3, 0xfd, 0x9c, + 0xb2, 0xb5, 0x31, 0xfc, 0x34, 0xcc, 0x71, 0xfa, 0x96, 0xdf, 0x4e, 0x93, 0x5c, 0x75, 0x75, 0xb9, + 0x9e, 0xb6, 0x9b, 0xeb, 0x6a, 0xbb, 0x39, 0xd7, 0x61, 0x9b, 0x24, 0x4e, 0xbd, 0x7b, 0xa1, 0xce, + 0xbe, 0xb0, 0xf3, 0x8f, 0x19, 0x96, 0xc4, 0xf1, 0x5b, 0x1b, 0x7e, 0xc0, 0x0f, 0x2d, 0x6c, 0xa9, + 0x7c, 0x80, 0x99, 0xca, 0x16, 0xab, 0xb3, 0xee, 0x4a, 0xbf, 0x49, 0x29, 0xf6, 0x55, 0x27, 0x48, + 0xfc, 0x16, 0x5f, 0x3f, 0x35, 0x84, 0x7c, 0x80, 0x7f, 0xe5, 0xb7, 0x12, 0x42, 0x85, 0xc3, 0x08, + 0x2a, 0x33, 0xc6, 0x6a, 0xda, 0x41, 0x95, 0xfe, 0x9a, 0x9a, 0xed, 0x01, 0xd5, 0x6c, 0x7b, 0x5d, + 0xe1, 0xe0, 0x80, 0x36, 0x20, 0x6f, 0x28, 0xa7, 0x29, 0xc2, 0x38, 0x94, 0x16, 0x56, 0x92, 0xee, + 0x33, 0xe5, 0xf9, 0x62, 0x53, 0x3e, 0xac, 0x9b, 0xf2, 0xef, 0x10, 0x54, 0x36, 0xc2, 0xe6, 0x95, + 0x20, 0xa1, 0xbb, 0xfc, 0x84, 0x1d, 0x06, 0x09, 0x09, 0xb2, 0x86, 0x90, 0x20, 0xd9, 0x26, 0x24, + 0x7e, 0x9b, 0x6c, 0x26, 0x4e, 0x3b, 0x12, 0x15, 0xe4, 0x9e, 0x36, 0x21, 0xfb, 0x98, 0x29, 0xa6, + 0xe5, 0xc4, 0x09, 0xf7, 0xf8, 0x8a, 0xcd, 0x9f, 0x99, 0x08, 0xd9, 0x84, 0xcd, 0x84, 0x0a, 0x77, + 0xd7, 0xc6, 0x54, 0x13, 0x2b, 0xa7, 0xd8, 0x04, 0x69, 0xb5, 0xe1, 0xfe, 0xec, 0xe0, 0x78, 0x8b, + 0xd0, 0xb6, 0x1f, 0x38, 0xc5, 0xd1, 0x7b, 0x8c, 0x4e, 0x76, 0x41, 0xdf, 0x22, 0xd4, 0x9c, 0x8e, + 0x9d, 0xc3, 0x6e, 0xfb, 0x81, 0x17, 0xde, 0x2d, 0x70, 0x9e, 0xc9, 0x16, 0xfc, 0x8b, 0xde, 0x8c, + 0x56, 0x56, 0xcc, 0x3c, 0xfd, 0x69, 0x38, 0xc8, 0x62, 0x42, 0x97, 0x88, 0x17, 0x22, 0xec, 0x58, + 0xc3, 0x1a, 0x6d, 0x39, 0x0f, 0x5b, 0xff, 0x10, 0x6f, 0xc0, 0xbc, 0x13, 0xc7, 0x7e, 0x33, 0x20, + 0x9e, 0xe4, 0x55, 0x1a, 0x9b, 0x57, 0xef, 0xa7, 0x69, 0xcb, 0x86, 0xcf, 0x10, 0xfb, 0x2d, 0x49, + 0xeb, 0xab, 0x08, 0x8e, 0x0d, 0x64, 0x92, 0x79, 0x0e, 0x52, 0xc2, 0xb8, 0x09, 0x95, 0xd8, 0xdd, + 0x26, 0x5e, 0xa7, 0x25, 0x4f, 0x61, 0x19, 0xcd, 0xde, 0x79, 0x9d, 0x74, 0xf7, 0x45, 0x1a, 0xc9, + 0x68, 0x7c, 0x02, 0xa0, 0xed, 0x04, 0x1d, 0xa7, 0xc5, 0x21, 0x4c, 0x73, 0x08, 0xca, 0x88, 0xb5, + 0x08, 0xe6, 0x20, 0xd3, 0x11, 0xfd, 0xc1, 0x7f, 0x22, 0x38, 0x24, 0x83, 0xaa, 0xd8, 0xdd, 0x1a, + 0xcc, 0x2b, 0x6a, 0x50, 0xaa, 0xc5, 0xde, 0xe1, 0x11, 0x01, 0x53, 0x5a, 0xc9, 0x94, 0x7e, 0x9f, + 0xd4, 0xd5, 0x6e, 0x84, 0xc6, 0xce, 0x77, 0x68, 0x9f, 0xaa, 0xe3, 0xaf, 0x80, 0x71, 0xdd, 0x09, + 0x9c, 0x26, 0xf1, 0x32, 0xb1, 0x33, 0x13, 0x7b, 0x51, 0x6d, 0x74, 0x4d, 0xdc, 0x56, 0xca, 0x4a, + 0x2d, 0x7f, 0x6b, 0x4b, 0x36, 0xcd, 0x28, 0x54, 0x36, 0xfc, 0x60, 0xe7, 0x5a, 0xb0, 0x15, 0x32, + 0x89, 0x13, 0x3f, 0x69, 0x49, 0xed, 0xa6, 0x04, 0x3e, 0x0c, 0x53, 0x1d, 0xda, 0x12, 0x16, 0xc0, + 0x1e, 0xd9, 0x09, 0xdc, 0x23, 0xb1, 0x4b, 0xfd, 0x28, 0xc9, 0x2b, 0x6f, 0x75, 0x88, 0xed, 0x83, + 0xef, 0x86, 0xc1, 0x7a, 0xcb, 0x89, 0x63, 0x99, 0x80, 0xb2, 0x01, 0xeb, 0x71, 0x38, 0xc8, 0xd6, + 0xcc, 0xc5, 0x3c, 0xab, 0x8b, 0x79, 0x4c, 0x83, 0x2f, 0xe1, 0x49, 0xc4, 0x0e, 0xdc, 0xc7, 0xf2, + 0xfe, 0xa5, 0x28, 0x12, 0x4c, 0xc6, 0x2c, 0x87, 0xa6, 0x06, 0xe5, 0xcf, 0x81, 0xd7, 0x02, 0xab, + 0xef, 0x9c, 0x01, 0xac, 0xfa, 0x09, 0xa1, 0x5d, 0xdf, 0x25, 0xf8, 0x3b, 0x08, 0xa6, 0xd9, 0xd2, + 0xf8, 0x81, 0x61, 0x6e, 0xc9, 0xed, 0xd5, 0xdc, 0xbf, 0x63, 0x3e, 0x5b, 0xcd, 0x5a, 0x7c, 0xf5, + 0xaf, 0x7f, 0xff, 0x6e, 0x69, 0x01, 0x1f, 0xe5, 0x97, 0xc1, 0xdd, 0x0b, 0xea, 0xc5, 0x6c, 0x8c, + 0x5f, 0x47, 0x80, 0x45, 0x1d, 0xa4, 0x5c, 0x97, 0xe1, 0xb3, 0xc3, 0x20, 0x0e, 0xb8, 0x56, 0x33, + 0x1f, 0x50, 0xb2, 0x4a, 0xdd, 0x0d, 0x29, 0x61, 0x39, 0x84, 0x4f, 0xe0, 0x00, 0x96, 0x39, 0x80, + 0x53, 0xd8, 0x1a, 0x04, 0xa0, 0xf1, 0x32, 0xd3, 0xe8, 0x2b, 0x0d, 0x92, 0xae, 0xfb, 0x26, 0x82, + 0xf2, 0x6d, 0x7e, 0x86, 0x18, 0xa1, 0xa4, 0xcd, 0x7d, 0x53, 0x12, 0x5f, 0x8e, 0xa3, 0xb5, 0x4e, + 0x72, 0xa4, 0x0f, 0xe0, 0xe3, 0x12, 0x69, 0x9c, 0x50, 0xe2, 0xb4, 0x35, 0xc0, 0xe7, 0x11, 0x7e, + 0x0b, 0xc1, 0x4c, 0x7a, 0xf1, 0x80, 0x4f, 0x0f, 0x43, 0xa9, 0x5d, 0x4c, 0x98, 0xfb, 0xd7, 0x24, + 0xb3, 0x1e, 0xe6, 0x18, 0x4f, 0x5a, 0x03, 0xb7, 0x73, 0x4d, 0xeb, 0xf1, 0xbf, 0x81, 0x60, 0xea, + 0x2a, 0x19, 0x69, 0x6f, 0xfb, 0x08, 0xae, 0x4f, 0x81, 0x03, 0xb6, 0x1a, 0xff, 0x14, 0xc1, 0xfd, + 0x57, 0x49, 0x32, 0x38, 0x3d, 0xe2, 0xda, 0xe8, 0x9c, 0x25, 0xcc, 0xee, 0xec, 0x18, 0x33, 0xb3, + 0xbc, 0xd0, 0xe0, 0xc8, 0x1e, 0xc6, 0x67, 0x8a, 0x8c, 0x30, 0xde, 0x0d, 0xdc, 0xbb, 0x02, 0xc7, + 0x9f, 0x11, 0x1c, 0xee, 0xbd, 0x16, 0xc7, 0x7a, 0x42, 0x1d, 0x78, 0x6b, 0x6e, 0xde, 0x98, 0x34, + 0xca, 0xea, 0x4c, 0xad, 0x4b, 0x1c, 0xf9, 0x63, 0xf8, 0xd1, 0x22, 0xe4, 0x59, 0x17, 0xb7, 0xf1, + 0xb2, 0x7c, 0x7c, 0x85, 0xff, 0x84, 0x83, 0xc3, 0x7e, 0x17, 0xc1, 0x51, 0xc9, 0x77, 0x7d, 0xdb, + 0xa1, 0xc9, 0x65, 0xc2, 0x6a, 0xe8, 0x78, 0x2c, 0x79, 0x26, 0xcc, 0x1a, 0xea, 0x7a, 0xd6, 0x15, + 0x2e, 0xcb, 0xa7, 0xf1, 0x13, 0x7b, 0x96, 0xc5, 0x65, 0x6c, 0x3c, 0x01, 0xfb, 0x55, 0x04, 0x07, + 0xae, 0x92, 0xe4, 0x7a, 0x76, 0x93, 0x70, 0x7a, 0xac, 0xdb, 0x49, 0x73, 0xb1, 0xae, 0xfc, 0x72, + 0x44, 0xbe, 0xca, 0x4c, 0x64, 0x85, 0x83, 0x3b, 0x83, 0x4f, 0x17, 0x81, 0xcb, 0x6f, 0x2f, 0xde, + 0x44, 0x70, 0x4c, 0x05, 0x91, 0x5f, 0x42, 0x7f, 0x62, 0x6f, 0x77, 0xa5, 0xe2, 0xc6, 0x75, 0x04, + 0xba, 0x55, 0x8e, 0xee, 0x9c, 0x35, 0xd8, 0x80, 0xdb, 0x7d, 0x28, 0xd6, 0xd0, 0x72, 0x0d, 0xe1, + 0xdf, 0x23, 0x98, 0x49, 0x5b, 0xcd, 0xc3, 0x75, 0xa4, 0xdd, 0x42, 0xee, 0x67, 0x34, 0x10, 0xbb, + 0x6d, 0x9e, 0x1f, 0xac, 0x50, 0xf5, 0x7b, 0x69, 0xaa, 0x75, 0xae, 0x65, 0x3d, 0x8c, 0xbd, 0x8d, + 0x00, 0xf2, 0x76, 0x39, 0x7e, 0xb8, 0x58, 0x0e, 0xa5, 0xa5, 0x6e, 0xee, 0x6f, 0xc3, 0xdc, 0xaa, + 0x73, 0x79, 0x6a, 0xe6, 0x52, 0x61, 0x0c, 0x89, 0x88, 0xbb, 0x96, 0xb6, 0xd6, 0x7f, 0x82, 0xa0, + 0xcc, 0xfb, 0x78, 0xf8, 0xd4, 0x30, 0xcc, 0x6a, 0x9b, 0x6f, 0x3f, 0x55, 0xff, 0x10, 0x87, 0xba, + 0xb4, 0x5a, 0x14, 0x88, 0xd7, 0xd0, 0x32, 0xee, 0xc2, 0x4c, 0xda, 0x39, 0x1b, 0x6e, 0x1e, 0x5a, + 0x67, 0xcd, 0x5c, 0x2a, 0x28, 0x0c, 0x52, 0x43, 0x15, 0x39, 0x60, 0x79, 0x54, 0x0e, 0x98, 0x66, + 0x61, 0x1a, 0x9f, 0x2c, 0x0a, 0xe2, 0xff, 0x03, 0xc5, 0x9c, 0xe5, 0xe8, 0x4e, 0x5b, 0x4b, 0xa3, + 0xf2, 0x00, 0xd3, 0xce, 0xf7, 0x10, 0x1c, 0xee, 0x2d, 0xae, 0xf1, 0xf1, 0x9e, 0x98, 0xa9, 0x9e, + 0x35, 0x4c, 0x5d, 0x8b, 0xc3, 0x0a, 0x73, 0xeb, 0x33, 0x1c, 0xc5, 0x1a, 0x7e, 0x64, 0xa4, 0x67, + 0xdc, 0x90, 0x51, 0x87, 0x31, 0x5a, 0xc9, 0x6f, 0x56, 0x7f, 0x83, 0xe0, 0x80, 0xe4, 0x7b, 0x8b, + 0x12, 0x52, 0x0c, 0x6b, 0xff, 0x1c, 0x81, 0xad, 0x65, 0x3d, 0xce, 0xe1, 0x7f, 0x12, 0x5f, 0x1c, + 0x13, 0xbe, 0x84, 0xbd, 0x92, 0x30, 0xa4, 0x7f, 0x44, 0x70, 0xe4, 0x76, 0x6a, 0xf7, 0x1f, 0x12, + 0xfe, 0x75, 0x8e, 0xff, 0x09, 0xfc, 0x58, 0x41, 0x9d, 0x37, 0x4a, 0x8c, 0xf3, 0x08, 0xff, 0x0a, + 0x41, 0x45, 0xde, 0x19, 0xe1, 0x33, 0x43, 0x1d, 0x43, 0xbf, 0x55, 0xda, 0x4f, 0x63, 0x16, 0x45, + 0x8d, 0x75, 0xaa, 0x30, 0x9d, 0x8a, 0xf5, 0x99, 0x41, 0xbf, 0x81, 0x00, 0x67, 0x67, 0xe6, 0xec, + 0x14, 0x8d, 0x1f, 0xd2, 0x96, 0x1a, 0xda, 0x98, 0x31, 0xcf, 0x8c, 0x9c, 0xa7, 0xa7, 0xd2, 0xe5, + 0xc2, 0x54, 0x1a, 0x66, 0xeb, 0x7f, 0x13, 0x41, 0xf5, 0x2a, 0xc9, 0xce, 0x20, 0x05, 0xba, 0xd4, + 0xaf, 0xbc, 0xcc, 0xda, 0xe8, 0x89, 0x02, 0xd1, 0x39, 0x8e, 0xe8, 0x21, 0x5c, 0xac, 0x2a, 0x09, + 0xe0, 0x87, 0x08, 0x0e, 0xde, 0x54, 0x4d, 0x14, 0x9f, 0x1b, 0xb5, 0x92, 0x16, 0xc9, 0xc7, 0xc7, + 0xf5, 0x71, 0x8e, 0x6b, 0xc5, 0x1a, 0x0b, 0xd7, 0x9a, 0xb8, 0x5f, 0xf9, 0x11, 0x4a, 0x0f, 0xb1, + 0x3d, 0xfd, 0xec, 0xff, 0x56, 0x6f, 0x05, 0x6d, 0x71, 0xeb, 0x22, 0xc7, 0x57, 0xc7, 0xe7, 0xc6, + 0xc1, 0xd7, 0x10, 0x4d, 0x6e, 0xfc, 0x7d, 0x04, 0x47, 0xf8, 0x5d, 0x83, 0xca, 0xb8, 0x27, 0xc5, + 0x0c, 0xbb, 0x99, 0x18, 0x23, 0xc5, 0x88, 0xf8, 0x63, 0xed, 0x09, 0xd4, 0x9a, 0xbc, 0x47, 0x78, + 0x1b, 0x81, 0x29, 0x9d, 0xb2, 0xff, 0x17, 0x06, 0xb8, 0x5e, 0xe4, 0xc8, 0xfd, 0x3f, 0x41, 0x30, + 0x1b, 0x63, 0xcf, 0x17, 0xe8, 0x3f, 0xc5, 0xd1, 0x5f, 0x18, 0x81, 0x3e, 0xfd, 0x78, 0x45, 0xf5, + 0xde, 0x6f, 0x21, 0x38, 0x24, 0xb3, 0xb1, 0x30, 0xcb, 0x95, 0x51, 0x3b, 0xbe, 0xd7, 0xec, 0x2d, + 0xfc, 0x64, 0x79, 0x3c, 0x3f, 0xf9, 0x01, 0x82, 0x23, 0xf2, 0x67, 0x8f, 0x9b, 0xd4, 0xbd, 0x14, + 0x78, 0x97, 0xe3, 0x64, 0x78, 0x85, 0xd6, 0xf7, 0x93, 0x92, 0xe1, 0x8e, 0xd2, 0xfb, 0x63, 0x4a, + 0xeb, 0x02, 0x07, 0x76, 0xd6, 0x5a, 0x1c, 0x00, 0x6c, 0x45, 0xfe, 0x62, 0x41, 0x2f, 0x1c, 0xdf, + 0x42, 0x30, 0x2b, 0x2e, 0x49, 0x0a, 0x2a, 0x30, 0xe5, 0x16, 0xc5, 0xec, 0x69, 0x1d, 0x89, 0x1e, + 0xbb, 0xf5, 0x05, 0xbe, 0xf6, 0x73, 0xb8, 0x51, 0xa4, 0x94, 0x28, 0xf4, 0xe2, 0xc6, 0xcb, 0xa2, + 0xc1, 0xfd, 0x4a, 0xa3, 0x15, 0x36, 0xe3, 0x17, 0x2c, 0x5c, 0x58, 0x67, 0xb0, 0x39, 0xe7, 0x11, + 0x4e, 0x60, 0x8e, 0xf9, 0x1c, 0xef, 0x47, 0xe1, 0xa5, 0x9e, 0xee, 0x55, 0x5f, 0xab, 0xca, 0x34, + 0xfb, 0xfa, 0x5b, 0x79, 0x61, 0x21, 0xba, 0x03, 0xf8, 0xc1, 0xc2, 0x65, 0xf9, 0x42, 0xaf, 0x23, + 0x38, 0xa2, 0x06, 0x91, 0x74, 0xf9, 0xb1, 0x43, 0x48, 0x11, 0x0a, 0x71, 0x56, 0xc1, 0xcb, 0x63, + 0xf9, 0x67, 0x0a, 0xe7, 0x6b, 0x08, 0x8e, 0x5c, 0x25, 0x89, 0x7e, 0x83, 0xde, 0x73, 0x40, 0x1d, + 0xf8, 0x2b, 0x00, 0xf3, 0x64, 0xe1, 0x1c, 0x01, 0xa9, 0xa8, 0x09, 0xc5, 0x0e, 0x97, 0xca, 0x37, + 0x4f, 0x3e, 0xf5, 0xa7, 0xf7, 0x4f, 0xa0, 0xf7, 0xde, 0x3f, 0x81, 0xfe, 0xf6, 0xfe, 0x09, 0xf4, + 0xc2, 0x23, 0xe3, 0xfd, 0xc3, 0x83, 0xdb, 0xf2, 0x49, 0x90, 0xa8, 0x6c, 0xff, 0x13, 0x00, 0x00, + 0xff, 0xff, 0x31, 0x6d, 0xd9, 0xbc, 0xd6, 0x31, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -3077,14 +3455,19 @@ type ApplicationServiceClient interface { ListResourceActions(ctx context.Context, in *ApplicationResourceRequest, opts ...grpc.CallOption) (*ResourceActionsListResponse, error) // RunResourceAction run resource action RunResourceAction(ctx context.Context, in *ResourceActionRunRequest, opts ...grpc.CallOption) (*ApplicationResponse, error) + // Rollback application rollout + RollbackApplicationRollout(ctx context.Context, in *ApplicationRolloutRollbackRequest, opts ...grpc.CallOption) (*ApplicationRolloutRollbackResponse, error) // DeleteResource deletes a single application resource DeleteResource(ctx context.Context, in *ApplicationResourceDeleteRequest, opts ...grpc.CallOption) (*ApplicationResponse, error) + // Create creates an application + ValidateSrcAndDst(ctx context.Context, in *ApplicationValidationRequest, opts ...grpc.CallOption) (*ApplicationValidateResponse, error) // PodLogs returns stream of log entries for the specified pod. Pod PodLogs(ctx context.Context, in *ApplicationPodLogsQuery, opts ...grpc.CallOption) (ApplicationService_PodLogsClient, error) // ListLinks returns the list of all application deep links ListLinks(ctx context.Context, in *ListAppLinksRequest, opts ...grpc.CallOption) (*LinksResponse, error) // ListResourceLinks returns the list of all resource deep links ListResourceLinks(ctx context.Context, in *ApplicationResourceRequest, opts ...grpc.CallOption) (*LinksResponse, error) + GetChangeRevision(ctx context.Context, in *ChangeRevisionRequest, opts ...grpc.CallOption) (*ChangeRevisionResponse, error) } type applicationServiceClient struct { @@ -3382,6 +3765,15 @@ func (c *applicationServiceClient) RunResourceAction(ctx context.Context, in *Re return out, nil } +func (c *applicationServiceClient) RollbackApplicationRollout(ctx context.Context, in *ApplicationRolloutRollbackRequest, opts ...grpc.CallOption) (*ApplicationRolloutRollbackResponse, error) { + out := new(ApplicationRolloutRollbackResponse) + err := c.cc.Invoke(ctx, "/application.ApplicationService/RollbackApplicationRollout", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *applicationServiceClient) DeleteResource(ctx context.Context, in *ApplicationResourceDeleteRequest, opts ...grpc.CallOption) (*ApplicationResponse, error) { out := new(ApplicationResponse) err := c.cc.Invoke(ctx, "/application.ApplicationService/DeleteResource", in, out, opts...) @@ -3391,6 +3783,15 @@ func (c *applicationServiceClient) DeleteResource(ctx context.Context, in *Appli return out, nil } +func (c *applicationServiceClient) ValidateSrcAndDst(ctx context.Context, in *ApplicationValidationRequest, opts ...grpc.CallOption) (*ApplicationValidateResponse, error) { + out := new(ApplicationValidateResponse) + err := c.cc.Invoke(ctx, "/application.ApplicationService/ValidateSrcAndDst", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *applicationServiceClient) PodLogs(ctx context.Context, in *ApplicationPodLogsQuery, opts ...grpc.CallOption) (ApplicationService_PodLogsClient, error) { stream, err := c.cc.NewStream(ctx, &_ApplicationService_serviceDesc.Streams[3], "/application.ApplicationService/PodLogs", opts...) if err != nil { @@ -3441,6 +3842,15 @@ func (c *applicationServiceClient) ListResourceLinks(ctx context.Context, in *Ap return out, nil } +func (c *applicationServiceClient) GetChangeRevision(ctx context.Context, in *ChangeRevisionRequest, opts ...grpc.CallOption) (*ChangeRevisionResponse, error) { + out := new(ChangeRevisionResponse) + err := c.cc.Invoke(ctx, "/application.ApplicationService/GetChangeRevision", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // ApplicationServiceServer is the server API for ApplicationService service. type ApplicationServiceServer interface { // List returns list of applications @@ -3491,14 +3901,19 @@ type ApplicationServiceServer interface { ListResourceActions(context.Context, *ApplicationResourceRequest) (*ResourceActionsListResponse, error) // RunResourceAction run resource action RunResourceAction(context.Context, *ResourceActionRunRequest) (*ApplicationResponse, error) + // Rollback application rollout + RollbackApplicationRollout(context.Context, *ApplicationRolloutRollbackRequest) (*ApplicationRolloutRollbackResponse, error) // DeleteResource deletes a single application resource DeleteResource(context.Context, *ApplicationResourceDeleteRequest) (*ApplicationResponse, error) + // Create creates an application + ValidateSrcAndDst(context.Context, *ApplicationValidationRequest) (*ApplicationValidateResponse, error) // PodLogs returns stream of log entries for the specified pod. Pod PodLogs(*ApplicationPodLogsQuery, ApplicationService_PodLogsServer) error // ListLinks returns the list of all application deep links ListLinks(context.Context, *ListAppLinksRequest) (*LinksResponse, error) // ListResourceLinks returns the list of all resource deep links ListResourceLinks(context.Context, *ApplicationResourceRequest) (*LinksResponse, error) + GetChangeRevision(context.Context, *ChangeRevisionRequest) (*ChangeRevisionResponse, error) } // UnimplementedApplicationServiceServer can be embedded to have forward compatible implementations. @@ -3577,9 +3992,15 @@ func (*UnimplementedApplicationServiceServer) ListResourceActions(ctx context.Co func (*UnimplementedApplicationServiceServer) RunResourceAction(ctx context.Context, req *ResourceActionRunRequest) (*ApplicationResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method RunResourceAction not implemented") } +func (*UnimplementedApplicationServiceServer) RollbackApplicationRollout(ctx context.Context, req *ApplicationRolloutRollbackRequest) (*ApplicationRolloutRollbackResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method RollbackApplicationRollout not implemented") +} func (*UnimplementedApplicationServiceServer) DeleteResource(ctx context.Context, req *ApplicationResourceDeleteRequest) (*ApplicationResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method DeleteResource not implemented") } +func (*UnimplementedApplicationServiceServer) ValidateSrcAndDst(ctx context.Context, req *ApplicationValidationRequest) (*ApplicationValidateResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ValidateSrcAndDst not implemented") +} func (*UnimplementedApplicationServiceServer) PodLogs(req *ApplicationPodLogsQuery, srv ApplicationService_PodLogsServer) error { return status.Errorf(codes.Unimplemented, "method PodLogs not implemented") } @@ -3589,6 +4010,9 @@ func (*UnimplementedApplicationServiceServer) ListLinks(ctx context.Context, req func (*UnimplementedApplicationServiceServer) ListResourceLinks(ctx context.Context, req *ApplicationResourceRequest) (*LinksResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method ListResourceLinks not implemented") } +func (*UnimplementedApplicationServiceServer) GetChangeRevision(ctx context.Context, req *ChangeRevisionRequest) (*ChangeRevisionResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetChangeRevision not implemented") +} func RegisterApplicationServiceServer(s *grpc.Server, srv ApplicationServiceServer) { s.RegisterService(&_ApplicationService_serviceDesc, srv) @@ -4040,6 +4464,24 @@ func _ApplicationService_RunResourceAction_Handler(srv interface{}, ctx context. return interceptor(ctx, in, info, handler) } +func _ApplicationService_RollbackApplicationRollout_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ApplicationRolloutRollbackRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ApplicationServiceServer).RollbackApplicationRollout(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/application.ApplicationService/RollbackApplicationRollout", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ApplicationServiceServer).RollbackApplicationRollout(ctx, req.(*ApplicationRolloutRollbackRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _ApplicationService_DeleteResource_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(ApplicationResourceDeleteRequest) if err := dec(in); err != nil { @@ -4058,6 +4500,24 @@ func _ApplicationService_DeleteResource_Handler(srv interface{}, ctx context.Con return interceptor(ctx, in, info, handler) } +func _ApplicationService_ValidateSrcAndDst_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ApplicationValidationRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ApplicationServiceServer).ValidateSrcAndDst(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/application.ApplicationService/ValidateSrcAndDst", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ApplicationServiceServer).ValidateSrcAndDst(ctx, req.(*ApplicationValidationRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _ApplicationService_PodLogs_Handler(srv interface{}, stream grpc.ServerStream) error { m := new(ApplicationPodLogsQuery) if err := stream.RecvMsg(m); err != nil { @@ -4115,6 +4575,24 @@ func _ApplicationService_ListResourceLinks_Handler(srv interface{}, ctx context. return interceptor(ctx, in, info, handler) } +func _ApplicationService_GetChangeRevision_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ChangeRevisionRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ApplicationServiceServer).GetChangeRevision(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/application.ApplicationService/GetChangeRevision", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ApplicationServiceServer).GetChangeRevision(ctx, req.(*ChangeRevisionRequest)) + } + return interceptor(ctx, in, info, handler) +} + var _ApplicationService_serviceDesc = grpc.ServiceDesc{ ServiceName: "application.ApplicationService", HandlerType: (*ApplicationServiceServer)(nil), @@ -4203,10 +4681,18 @@ var _ApplicationService_serviceDesc = grpc.ServiceDesc{ MethodName: "RunResourceAction", Handler: _ApplicationService_RunResourceAction_Handler, }, + { + MethodName: "RollbackApplicationRollout", + Handler: _ApplicationService_RollbackApplicationRollout_Handler, + }, { MethodName: "DeleteResource", Handler: _ApplicationService_DeleteResource_Handler, }, + { + MethodName: "ValidateSrcAndDst", + Handler: _ApplicationService_ValidateSrcAndDst_Handler, + }, { MethodName: "ListLinks", Handler: _ApplicationService_ListLinks_Handler, @@ -4215,6 +4701,10 @@ var _ApplicationService_serviceDesc = grpc.ServiceDesc{ MethodName: "ListResourceLinks", Handler: _ApplicationService_ListResourceLinks_Handler, }, + { + MethodName: "GetChangeRevision", + Handler: _ApplicationService_GetChangeRevision_Handler, + }, }, Streams: []grpc.StreamDesc{ { @@ -4677,6 +5167,90 @@ func (m *ApplicationManifestQueryWithFiles) MarshalToSizedBuffer(dAtA []byte) (i return len(dAtA) - i, nil } +func (m *ApplicationValidateResponse) 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 *ApplicationValidateResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ApplicationValidateResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if m.Entity != nil { + i -= len(*m.Entity) + copy(dAtA[i:], *m.Entity) + i = encodeVarintApplication(dAtA, i, uint64(len(*m.Entity))) + i-- + dAtA[i] = 0x12 + } + if m.Error != nil { + i -= len(*m.Error) + copy(dAtA[i:], *m.Error) + i = encodeVarintApplication(dAtA, i, uint64(len(*m.Error))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *ApplicationRolloutRollbackResponse) 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 *ApplicationRolloutRollbackResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ApplicationRolloutRollbackResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if m.NewRevision == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("newRevision") + } else { + i = encodeVarintApplication(dAtA, i, uint64(*m.NewRevision)) + i-- + dAtA[i] = 0x10 + } + if m.Rollout == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("rollout") + } else { + i -= len(*m.Rollout) + copy(dAtA[i:], *m.Rollout) + i = encodeVarintApplication(dAtA, i, uint64(len(*m.Rollout))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + func (m *ApplicationManifestQueryWithFilesWrapper) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -5170,6 +5744,117 @@ func (m *ApplicationSyncRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) return len(dAtA) - i, nil } +func (m *ApplicationValidationRequest) 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 *ApplicationValidationRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ApplicationValidationRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if m.Application == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("application") + } else { + { + size, err := m.Application.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintApplication(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *ApplicationRolloutRollbackRequest) 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 *ApplicationRolloutRollbackRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ApplicationRolloutRollbackRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if m.RolloutRevision == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("rolloutRevision") + } else { + i = encodeVarintApplication(dAtA, i, uint64(*m.RolloutRevision)) + i-- + dAtA[i] = 0x28 + } + if m.RolloutNamespace == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("rolloutNamespace") + } else { + i -= len(*m.RolloutNamespace) + copy(dAtA[i:], *m.RolloutNamespace) + i = encodeVarintApplication(dAtA, i, uint64(len(*m.RolloutNamespace))) + i-- + dAtA[i] = 0x22 + } + if m.RolloutName == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("rolloutName") + } else { + i -= len(*m.RolloutName) + copy(dAtA[i:], *m.RolloutName) + i = encodeVarintApplication(dAtA, i, uint64(len(*m.RolloutName))) + i-- + dAtA[i] = 0x1a + } + if m.Namespace == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("namespace") + } else { + i -= len(*m.Namespace) + copy(dAtA[i:], *m.Namespace) + i = encodeVarintApplication(dAtA, i, uint64(len(*m.Namespace))) + i-- + dAtA[i] = 0x12 + } + if m.Name == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("name") + } else { + i -= len(*m.Name) + copy(dAtA[i:], *m.Name) + i = encodeVarintApplication(dAtA, i, uint64(len(*m.Name))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + func (m *ApplicationUpdateSpecRequest) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -5480,7 +6165,7 @@ func (m *ApplicationResourceRequest) MarshalToSizedBuffer(dAtA []byte) (int, err return len(dAtA) - i, nil } -func (m *ApplicationResourcePatchRequest) Marshal() (dAtA []byte, err error) { +func (m *ChangeRevisionRequest) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -5490,12 +6175,12 @@ func (m *ApplicationResourcePatchRequest) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *ApplicationResourcePatchRequest) MarshalTo(dAtA []byte) (int, error) { +func (m *ChangeRevisionRequest) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *ApplicationResourcePatchRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *ChangeRevisionRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int @@ -5504,24 +6189,117 @@ func (m *ApplicationResourcePatchRequest) MarshalToSizedBuffer(dAtA []byte) (int i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } - if m.Project != nil { - i -= len(*m.Project) - copy(dAtA[i:], *m.Project) - i = encodeVarintApplication(dAtA, i, uint64(len(*m.Project))) + if m.PreviousRevision != nil { + i -= len(*m.PreviousRevision) + copy(dAtA[i:], *m.PreviousRevision) + i = encodeVarintApplication(dAtA, i, uint64(len(*m.PreviousRevision))) i-- - dAtA[i] = 0x52 + dAtA[i] = 0x22 } - if m.AppNamespace != nil { - i -= len(*m.AppNamespace) - copy(dAtA[i:], *m.AppNamespace) - i = encodeVarintApplication(dAtA, i, uint64(len(*m.AppNamespace))) + if m.CurrentRevision != nil { + i -= len(*m.CurrentRevision) + copy(dAtA[i:], *m.CurrentRevision) + i = encodeVarintApplication(dAtA, i, uint64(len(*m.CurrentRevision))) i-- - dAtA[i] = 0x4a + dAtA[i] = 0x1a } - if m.PatchType == nil { - return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("patchType") - } else { - i -= len(*m.PatchType) + if m.Namespace != nil { + i -= len(*m.Namespace) + copy(dAtA[i:], *m.Namespace) + i = encodeVarintApplication(dAtA, i, uint64(len(*m.Namespace))) + i-- + dAtA[i] = 0x12 + } + if m.AppName == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("appName") + } else { + i -= len(*m.AppName) + copy(dAtA[i:], *m.AppName) + i = encodeVarintApplication(dAtA, i, uint64(len(*m.AppName))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *ChangeRevisionResponse) 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 *ChangeRevisionResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ChangeRevisionResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if m.Revision == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("revision") + } else { + i -= len(*m.Revision) + copy(dAtA[i:], *m.Revision) + i = encodeVarintApplication(dAtA, i, uint64(len(*m.Revision))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *ApplicationResourcePatchRequest) 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 *ApplicationResourcePatchRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ApplicationResourcePatchRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if m.Project != nil { + i -= len(*m.Project) + copy(dAtA[i:], *m.Project) + i = encodeVarintApplication(dAtA, i, uint64(len(*m.Project))) + i-- + dAtA[i] = 0x52 + } + if m.AppNamespace != nil { + i -= len(*m.AppNamespace) + copy(dAtA[i:], *m.AppNamespace) + i = encodeVarintApplication(dAtA, i, uint64(len(*m.AppNamespace))) + i-- + dAtA[i] = 0x4a + } + if m.PatchType == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("patchType") + } else { + i -= len(*m.PatchType) copy(dAtA[i:], *m.PatchType) i = encodeVarintApplication(dAtA, i, uint64(len(*m.PatchType))) i-- @@ -6875,6 +7653,45 @@ func (m *ApplicationManifestQueryWithFiles) Size() (n int) { return n } +func (m *ApplicationValidateResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Error != nil { + l = len(*m.Error) + n += 1 + l + sovApplication(uint64(l)) + } + if m.Entity != nil { + l = len(*m.Entity) + n += 1 + l + sovApplication(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *ApplicationRolloutRollbackResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Rollout != nil { + l = len(*m.Rollout) + n += 1 + l + sovApplication(uint64(l)) + } + if m.NewRevision != nil { + n += 1 + sovApplication(uint64(*m.NewRevision)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + func (m *ApplicationManifestQueryWithFilesWrapper) Size() (n int) { if m == nil { return 0 @@ -7095,6 +7912,53 @@ func (m *ApplicationSyncRequest) Size() (n int) { return n } +func (m *ApplicationValidationRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Application != nil { + l = m.Application.Size() + n += 1 + l + sovApplication(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *ApplicationRolloutRollbackRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Name != nil { + l = len(*m.Name) + n += 1 + l + sovApplication(uint64(l)) + } + if m.Namespace != nil { + l = len(*m.Namespace) + n += 1 + l + sovApplication(uint64(l)) + } + if m.RolloutName != nil { + l = len(*m.RolloutName) + n += 1 + l + sovApplication(uint64(l)) + } + if m.RolloutNamespace != nil { + l = len(*m.RolloutNamespace) + n += 1 + l + sovApplication(uint64(l)) + } + if m.RolloutRevision != nil { + n += 1 + sovApplication(uint64(*m.RolloutRevision)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + func (m *ApplicationUpdateSpecRequest) Size() (n int) { if m == nil { return 0 @@ -7235,6 +8099,50 @@ func (m *ApplicationResourceRequest) Size() (n int) { return n } +func (m *ChangeRevisionRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.AppName != nil { + l = len(*m.AppName) + n += 1 + l + sovApplication(uint64(l)) + } + if m.Namespace != nil { + l = len(*m.Namespace) + n += 1 + l + sovApplication(uint64(l)) + } + if m.CurrentRevision != nil { + l = len(*m.CurrentRevision) + n += 1 + l + sovApplication(uint64(l)) + } + if m.PreviousRevision != nil { + l = len(*m.PreviousRevision) + n += 1 + l + sovApplication(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *ChangeRevisionResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Revision != nil { + l = len(*m.Revision) + n += 1 + l + sovApplication(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + func (m *ApplicationResourcePatchRequest) Size() (n int) { if m == nil { return 0 @@ -9268,7 +10176,7 @@ func (m *ApplicationManifestQueryWithFiles) Unmarshal(dAtA []byte) error { } return nil } -func (m *ApplicationManifestQueryWithFilesWrapper) Unmarshal(dAtA []byte) error { +func (m *ApplicationValidateResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -9291,17 +10199,17 @@ func (m *ApplicationManifestQueryWithFilesWrapper) Unmarshal(dAtA []byte) error fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: ApplicationManifestQueryWithFilesWrapper: wiretype end group for non-group") + return fmt.Errorf("proto: ApplicationValidateResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: ApplicationManifestQueryWithFilesWrapper: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: ApplicationValidateResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Query", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Error", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowApplication @@ -9311,32 +10219,30 @@ func (m *ApplicationManifestQueryWithFilesWrapper) Unmarshal(dAtA []byte) error } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthApplication } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthApplication } if postIndex > l { return io.ErrUnexpectedEOF } - v := &ApplicationManifestQueryWithFiles{} - if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - m.Part = &ApplicationManifestQueryWithFilesWrapper_Query{v} + s := string(dAtA[iNdEx:postIndex]) + m.Error = &s iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Chunk", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Entity", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowApplication @@ -9346,26 +10252,24 @@ func (m *ApplicationManifestQueryWithFilesWrapper) Unmarshal(dAtA []byte) error } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthApplication } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthApplication } if postIndex > l { return io.ErrUnexpectedEOF } - v := &FileChunk{} - if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - m.Part = &ApplicationManifestQueryWithFilesWrapper_Chunk{v} + s := string(dAtA[iNdEx:postIndex]) + m.Entity = &s iNdEx = postIndex default: iNdEx = preIndex @@ -9389,7 +10293,8 @@ func (m *ApplicationManifestQueryWithFilesWrapper) Unmarshal(dAtA []byte) error } return nil } -func (m *ApplicationResponse) Unmarshal(dAtA []byte) error { +func (m *ApplicationRolloutRollbackResponse) Unmarshal(dAtA []byte) error { + var hasFields [1]uint64 l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -9412,22 +10317,255 @@ func (m *ApplicationResponse) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: ApplicationResponse: wiretype end group for non-group") + return fmt.Errorf("proto: ApplicationRolloutRollbackResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: ApplicationResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: ApplicationRolloutRollbackResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { - default: - iNdEx = preIndex - skippy, err := skipApplication(dAtA[iNdEx:]) - if err != nil { - return err + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Rollout", wireType) } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthApplication + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowApplication + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } } - if (iNdEx + skippy) > l { + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthApplication + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthApplication + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(dAtA[iNdEx:postIndex]) + m.Rollout = &s + iNdEx = postIndex + hasFields[0] |= uint64(0x00000001) + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field NewRevision", wireType) + } + var v int64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowApplication + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.NewRevision = &v + hasFields[0] |= uint64(0x00000002) + default: + iNdEx = preIndex + skippy, err := skipApplication(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthApplication + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + if hasFields[0]&uint64(0x00000001) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("rollout") + } + if hasFields[0]&uint64(0x00000002) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("newRevision") + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ApplicationManifestQueryWithFilesWrapper) 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 ErrIntOverflowApplication + } + 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: ApplicationManifestQueryWithFilesWrapper: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ApplicationManifestQueryWithFilesWrapper: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Query", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowApplication + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthApplication + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthApplication + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := &ApplicationManifestQueryWithFiles{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Part = &ApplicationManifestQueryWithFilesWrapper_Query{v} + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Chunk", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowApplication + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthApplication + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthApplication + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := &FileChunk{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Part = &ApplicationManifestQueryWithFilesWrapper_Chunk{v} + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipApplication(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthApplication + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ApplicationResponse) 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 ErrIntOverflowApplication + } + 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: ApplicationResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ApplicationResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipApplication(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthApplication + } + if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF } m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) @@ -10558,7 +11696,7 @@ func (m *ApplicationSyncRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *ApplicationUpdateSpecRequest) Unmarshal(dAtA []byte) error { +func (m *ApplicationValidationRequest) Unmarshal(dAtA []byte) error { var hasFields [1]uint64 l := len(dAtA) iNdEx := 0 @@ -10582,17 +11720,17 @@ func (m *ApplicationUpdateSpecRequest) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: ApplicationUpdateSpecRequest: wiretype end group for non-group") + return fmt.Errorf("proto: ApplicationValidationRequest: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: ApplicationUpdateSpecRequest: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: ApplicationValidationRequest: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Application", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowApplication @@ -10602,155 +11740,34 @@ func (m *ApplicationUpdateSpecRequest) 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 ErrInvalidLengthApplication } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthApplication } if postIndex > l { return io.ErrUnexpectedEOF } - s := string(dAtA[iNdEx:postIndex]) - m.Name = &s + if m.Application == nil { + m.Application = &v1alpha1.Application{} + } + if err := m.Application.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex hasFields[0] |= uint64(0x00000001) - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Spec", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowApplication - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthApplication - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthApplication - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Spec == nil { - m.Spec = &v1alpha1.ApplicationSpec{} - } - if err := m.Spec.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - hasFields[0] |= uint64(0x00000002) - case 3: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Validate", wireType) - } - var v int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowApplication - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - b := bool(v != 0) - m.Validate = &b - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field AppNamespace", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowApplication - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthApplication - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthApplication - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - s := string(dAtA[iNdEx:postIndex]) - m.AppNamespace = &s - iNdEx = postIndex - case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Project", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowApplication - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthApplication - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthApplication - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - s := string(dAtA[iNdEx:postIndex]) - m.Project = &s - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipApplication(dAtA[iNdEx:]) - if err != nil { - return err + default: + iNdEx = preIndex + skippy, err := skipApplication(dAtA[iNdEx:]) + if err != nil { + return err } if (skippy < 0) || (iNdEx+skippy) < 0 { return ErrInvalidLengthApplication @@ -10763,10 +11780,7 @@ func (m *ApplicationUpdateSpecRequest) Unmarshal(dAtA []byte) error { } } if hasFields[0]&uint64(0x00000001) == 0 { - return github_com_gogo_protobuf_proto.NewRequiredNotSetError("name") - } - if hasFields[0]&uint64(0x00000002) == 0 { - return github_com_gogo_protobuf_proto.NewRequiredNotSetError("spec") + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("application") } if iNdEx > l { @@ -10774,7 +11788,7 @@ func (m *ApplicationUpdateSpecRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *ApplicationPatchRequest) Unmarshal(dAtA []byte) error { +func (m *ApplicationRolloutRollbackRequest) Unmarshal(dAtA []byte) error { var hasFields [1]uint64 l := len(dAtA) iNdEx := 0 @@ -10798,10 +11812,10 @@ func (m *ApplicationPatchRequest) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: ApplicationPatchRequest: wiretype end group for non-group") + return fmt.Errorf("proto: ApplicationRolloutRollbackRequest: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: ApplicationPatchRequest: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: ApplicationRolloutRollbackRequest: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -10840,7 +11854,7 @@ func (m *ApplicationPatchRequest) Unmarshal(dAtA []byte) error { hasFields[0] |= uint64(0x00000001) case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Patch", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Namespace", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -10869,12 +11883,12 @@ func (m *ApplicationPatchRequest) Unmarshal(dAtA []byte) error { return io.ErrUnexpectedEOF } s := string(dAtA[iNdEx:postIndex]) - m.Patch = &s + m.Namespace = &s iNdEx = postIndex hasFields[0] |= uint64(0x00000002) case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field PatchType", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field RolloutName", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -10903,12 +11917,12 @@ func (m *ApplicationPatchRequest) Unmarshal(dAtA []byte) error { return io.ErrUnexpectedEOF } s := string(dAtA[iNdEx:postIndex]) - m.PatchType = &s + m.RolloutName = &s iNdEx = postIndex hasFields[0] |= uint64(0x00000004) - case 5: + case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field AppNamespace", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field RolloutNamespace", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -10937,13 +11951,14 @@ func (m *ApplicationPatchRequest) Unmarshal(dAtA []byte) error { return io.ErrUnexpectedEOF } s := string(dAtA[iNdEx:postIndex]) - m.AppNamespace = &s + m.RolloutNamespace = &s iNdEx = postIndex - case 6: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Project", wireType) + hasFields[0] |= uint64(0x00000008) + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field RolloutRevision", wireType) } - var stringLen uint64 + var v int64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowApplication @@ -10953,25 +11968,13 @@ func (m *ApplicationPatchRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + v |= int64(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthApplication - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthApplication - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - s := string(dAtA[iNdEx:postIndex]) - m.Project = &s - iNdEx = postIndex + m.RolloutRevision = &v + hasFields[0] |= uint64(0x00000010) default: iNdEx = preIndex skippy, err := skipApplication(dAtA[iNdEx:]) @@ -10992,10 +11995,16 @@ func (m *ApplicationPatchRequest) Unmarshal(dAtA []byte) error { return github_com_gogo_protobuf_proto.NewRequiredNotSetError("name") } if hasFields[0]&uint64(0x00000002) == 0 { - return github_com_gogo_protobuf_proto.NewRequiredNotSetError("patch") + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("namespace") } if hasFields[0]&uint64(0x00000004) == 0 { - return github_com_gogo_protobuf_proto.NewRequiredNotSetError("patchType") + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("rolloutName") + } + if hasFields[0]&uint64(0x00000008) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("rolloutNamespace") + } + if hasFields[0]&uint64(0x00000010) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("rolloutRevision") } if iNdEx > l { @@ -11003,7 +12012,7 @@ func (m *ApplicationPatchRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *ApplicationRollbackRequest) Unmarshal(dAtA []byte) error { +func (m *ApplicationUpdateSpecRequest) Unmarshal(dAtA []byte) error { var hasFields [1]uint64 l := len(dAtA) iNdEx := 0 @@ -11027,10 +12036,10 @@ func (m *ApplicationRollbackRequest) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: ApplicationRollbackRequest: wiretype end group for non-group") + return fmt.Errorf("proto: ApplicationUpdateSpecRequest: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: ApplicationRollbackRequest: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: ApplicationUpdateSpecRequest: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -11068,10 +12077,10 @@ func (m *ApplicationRollbackRequest) Unmarshal(dAtA []byte) error { iNdEx = postIndex hasFields[0] |= uint64(0x00000001) case 2: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Spec", wireType) } - var v int64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowApplication @@ -11081,16 +12090,32 @@ func (m *ApplicationRollbackRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - v |= int64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - m.Id = &v + if msglen < 0 { + return ErrInvalidLengthApplication + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthApplication + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Spec == nil { + m.Spec = &v1alpha1.ApplicationSpec{} + } + if err := m.Spec.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex hasFields[0] |= uint64(0x00000002) case 3: if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field DryRun", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Validate", wireType) } var v int for shift := uint(0); ; shift += 7 { @@ -11108,29 +12133,8 @@ func (m *ApplicationRollbackRequest) Unmarshal(dAtA []byte) error { } } b := bool(v != 0) - m.DryRun = &b + m.Validate = &b case 4: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Prune", wireType) - } - var v int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowApplication - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - b := bool(v != 0) - m.Prune = &b - case 6: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field AppNamespace", wireType) } @@ -11163,7 +12167,7 @@ func (m *ApplicationRollbackRequest) Unmarshal(dAtA []byte) error { s := string(dAtA[iNdEx:postIndex]) m.AppNamespace = &s iNdEx = postIndex - case 7: + case 5: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Project", wireType) } @@ -11216,7 +12220,7 @@ func (m *ApplicationRollbackRequest) Unmarshal(dAtA []byte) error { return github_com_gogo_protobuf_proto.NewRequiredNotSetError("name") } if hasFields[0]&uint64(0x00000002) == 0 { - return github_com_gogo_protobuf_proto.NewRequiredNotSetError("id") + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("spec") } if iNdEx > l { @@ -11224,7 +12228,7 @@ func (m *ApplicationRollbackRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *ApplicationResourceRequest) Unmarshal(dAtA []byte) error { +func (m *ApplicationPatchRequest) Unmarshal(dAtA []byte) error { var hasFields [1]uint64 l := len(dAtA) iNdEx := 0 @@ -11248,10 +12252,10 @@ func (m *ApplicationResourceRequest) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: ApplicationResourceRequest: wiretype end group for non-group") + return fmt.Errorf("proto: ApplicationPatchRequest: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: ApplicationResourceRequest: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: ApplicationPatchRequest: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -11290,7 +12294,7 @@ func (m *ApplicationResourceRequest) Unmarshal(dAtA []byte) error { hasFields[0] |= uint64(0x00000001) case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Namespace", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Patch", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -11319,11 +12323,12 @@ func (m *ApplicationResourceRequest) Unmarshal(dAtA []byte) error { return io.ErrUnexpectedEOF } s := string(dAtA[iNdEx:postIndex]) - m.Namespace = &s + m.Patch = &s iNdEx = postIndex + hasFields[0] |= uint64(0x00000002) case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ResourceName", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field PatchType", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -11352,12 +12357,12 @@ func (m *ApplicationResourceRequest) Unmarshal(dAtA []byte) error { return io.ErrUnexpectedEOF } s := string(dAtA[iNdEx:postIndex]) - m.ResourceName = &s + m.PatchType = &s iNdEx = postIndex - hasFields[0] |= uint64(0x00000002) - case 4: + hasFields[0] |= uint64(0x00000004) + case 5: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Version", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field AppNamespace", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -11386,12 +12391,11 @@ func (m *ApplicationResourceRequest) Unmarshal(dAtA []byte) error { return io.ErrUnexpectedEOF } s := string(dAtA[iNdEx:postIndex]) - m.Version = &s + m.AppNamespace = &s iNdEx = postIndex - hasFields[0] |= uint64(0x00000004) - case 5: + case 6: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Group", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Project", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -11420,11 +12424,72 @@ func (m *ApplicationResourceRequest) Unmarshal(dAtA []byte) error { return io.ErrUnexpectedEOF } s := string(dAtA[iNdEx:postIndex]) - m.Group = &s + m.Project = &s iNdEx = postIndex - case 6: + default: + iNdEx = preIndex + skippy, err := skipApplication(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthApplication + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + if hasFields[0]&uint64(0x00000001) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("name") + } + if hasFields[0]&uint64(0x00000002) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("patch") + } + if hasFields[0]&uint64(0x00000004) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("patchType") + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ApplicationRollbackRequest) Unmarshal(dAtA []byte) error { + var hasFields [1]uint64 + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowApplication + } + 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: ApplicationRollbackRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ApplicationRollbackRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Kind", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -11453,10 +12518,73 @@ func (m *ApplicationResourceRequest) Unmarshal(dAtA []byte) error { return io.ErrUnexpectedEOF } s := string(dAtA[iNdEx:postIndex]) - m.Kind = &s + m.Name = &s iNdEx = postIndex - hasFields[0] |= uint64(0x00000008) - case 7: + hasFields[0] |= uint64(0x00000001) + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) + } + var v int64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowApplication + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Id = &v + hasFields[0] |= uint64(0x00000002) + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field DryRun", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowApplication + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + b := bool(v != 0) + m.DryRun = &b + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Prune", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowApplication + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + b := bool(v != 0) + m.Prune = &b + case 6: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field AppNamespace", wireType) } @@ -11489,7 +12617,7 @@ func (m *ApplicationResourceRequest) Unmarshal(dAtA []byte) error { s := string(dAtA[iNdEx:postIndex]) m.AppNamespace = &s iNdEx = postIndex - case 8: + case 7: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Project", wireType) } @@ -11542,13 +12670,616 @@ func (m *ApplicationResourceRequest) Unmarshal(dAtA []byte) error { return github_com_gogo_protobuf_proto.NewRequiredNotSetError("name") } if hasFields[0]&uint64(0x00000002) == 0 { - return github_com_gogo_protobuf_proto.NewRequiredNotSetError("resourceName") + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("id") } - if hasFields[0]&uint64(0x00000004) == 0 { - return github_com_gogo_protobuf_proto.NewRequiredNotSetError("version") + + if iNdEx > l { + return io.ErrUnexpectedEOF } - if hasFields[0]&uint64(0x00000008) == 0 { - return github_com_gogo_protobuf_proto.NewRequiredNotSetError("kind") + return nil +} +func (m *ApplicationResourceRequest) Unmarshal(dAtA []byte) error { + var hasFields [1]uint64 + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowApplication + } + 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: ApplicationResourceRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ApplicationResourceRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowApplication + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthApplication + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthApplication + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(dAtA[iNdEx:postIndex]) + m.Name = &s + iNdEx = postIndex + hasFields[0] |= uint64(0x00000001) + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Namespace", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowApplication + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthApplication + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthApplication + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(dAtA[iNdEx:postIndex]) + m.Namespace = &s + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ResourceName", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowApplication + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthApplication + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthApplication + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(dAtA[iNdEx:postIndex]) + m.ResourceName = &s + iNdEx = postIndex + hasFields[0] |= uint64(0x00000002) + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Version", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowApplication + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthApplication + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthApplication + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(dAtA[iNdEx:postIndex]) + m.Version = &s + iNdEx = postIndex + hasFields[0] |= uint64(0x00000004) + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Group", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowApplication + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthApplication + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthApplication + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(dAtA[iNdEx:postIndex]) + m.Group = &s + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Kind", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowApplication + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthApplication + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthApplication + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(dAtA[iNdEx:postIndex]) + m.Kind = &s + iNdEx = postIndex + hasFields[0] |= uint64(0x00000008) + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AppNamespace", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowApplication + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthApplication + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthApplication + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(dAtA[iNdEx:postIndex]) + m.AppNamespace = &s + iNdEx = postIndex + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Project", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowApplication + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthApplication + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthApplication + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(dAtA[iNdEx:postIndex]) + m.Project = &s + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipApplication(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthApplication + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + if hasFields[0]&uint64(0x00000001) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("name") + } + if hasFields[0]&uint64(0x00000002) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("resourceName") + } + if hasFields[0]&uint64(0x00000004) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("version") + } + if hasFields[0]&uint64(0x00000008) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("kind") + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ChangeRevisionRequest) Unmarshal(dAtA []byte) error { + var hasFields [1]uint64 + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowApplication + } + 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: ChangeRevisionRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ChangeRevisionRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AppName", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowApplication + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthApplication + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthApplication + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(dAtA[iNdEx:postIndex]) + m.AppName = &s + iNdEx = postIndex + hasFields[0] |= uint64(0x00000001) + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Namespace", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowApplication + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthApplication + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthApplication + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(dAtA[iNdEx:postIndex]) + m.Namespace = &s + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field CurrentRevision", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowApplication + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthApplication + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthApplication + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(dAtA[iNdEx:postIndex]) + m.CurrentRevision = &s + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PreviousRevision", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowApplication + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthApplication + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthApplication + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(dAtA[iNdEx:postIndex]) + m.PreviousRevision = &s + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipApplication(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthApplication + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + if hasFields[0]&uint64(0x00000001) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("appName") + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ChangeRevisionResponse) Unmarshal(dAtA []byte) error { + var hasFields [1]uint64 + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowApplication + } + 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: ChangeRevisionResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ChangeRevisionResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Revision", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowApplication + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthApplication + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthApplication + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(dAtA[iNdEx:postIndex]) + m.Revision = &s + iNdEx = postIndex + hasFields[0] |= uint64(0x00000001) + default: + iNdEx = preIndex + skippy, err := skipApplication(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthApplication + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + if hasFields[0]&uint64(0x00000001) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("revision") } if iNdEx > l { diff --git a/pkg/apiclient/application/application.pb.gw.go b/pkg/apiclient/application/application.pb.gw.go index ed6064cadb9a2..1110f199b3bcf 100644 --- a/pkg/apiclient/application/application.pb.gw.go +++ b/pkg/apiclient/application/application.pb.gw.go @@ -1709,6 +1709,76 @@ func local_request_ApplicationService_RunResourceAction_0(ctx context.Context, m } +func request_ApplicationService_RollbackApplicationRollout_0(ctx context.Context, marshaler runtime.Marshaler, client ApplicationServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ApplicationRolloutRollbackRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["name"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "name") + } + + protoReq.Name, err = runtime.StringP(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err) + } + + msg, err := client.RollbackApplicationRollout(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_ApplicationService_RollbackApplicationRollout_0(ctx context.Context, marshaler runtime.Marshaler, server ApplicationServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ApplicationRolloutRollbackRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["name"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "name") + } + + protoReq.Name, err = runtime.StringP(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err) + } + + msg, err := server.RollbackApplicationRollout(ctx, &protoReq) + return msg, metadata, err + +} + var ( filter_ApplicationService_DeleteResource_0 = &utilities.DoubleArray{Encoding: map[string]int{"name": 0}, Base: []int{1, 1, 0}, Check: []int{0, 1, 2}} ) @@ -1781,6 +1851,40 @@ func local_request_ApplicationService_DeleteResource_0(ctx context.Context, mars } +func request_ApplicationService_ValidateSrcAndDst_0(ctx context.Context, marshaler runtime.Marshaler, client ApplicationServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ApplicationValidationRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq.Application); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.ValidateSrcAndDst(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_ApplicationService_ValidateSrcAndDst_0(ctx context.Context, marshaler runtime.Marshaler, server ApplicationServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ApplicationValidationRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq.Application); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.ValidateSrcAndDst(ctx, &protoReq) + return msg, metadata, err + +} + var ( filter_ApplicationService_PodLogs_0 = &utilities.DoubleArray{Encoding: map[string]int{"name": 0, "podName": 1}, Base: []int{1, 1, 2, 0, 0}, Check: []int{0, 1, 1, 2, 3}} ) @@ -2028,6 +2132,42 @@ func local_request_ApplicationService_ListResourceLinks_0(ctx context.Context, m } +var ( + filter_ApplicationService_GetChangeRevision_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)} +) + +func request_ApplicationService_GetChangeRevision_0(ctx context.Context, marshaler runtime.Marshaler, client ApplicationServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ChangeRevisionRequest + var metadata runtime.ServerMetadata + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_ApplicationService_GetChangeRevision_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.GetChangeRevision(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_ApplicationService_GetChangeRevision_0(ctx context.Context, marshaler runtime.Marshaler, server ApplicationServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ChangeRevisionRequest + var metadata runtime.ServerMetadata + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_ApplicationService_GetChangeRevision_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.GetChangeRevision(ctx, &protoReq) + return msg, metadata, err + +} + // RegisterApplicationServiceHandlerServer registers the http handlers for service ApplicationService to "mux". // UnaryRPC :call ApplicationServiceServer directly. // StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. @@ -2538,6 +2678,29 @@ func RegisterApplicationServiceHandlerServer(ctx context.Context, mux *runtime.S }) + mux.Handle("POST", pattern_ApplicationService_RollbackApplicationRollout_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_ApplicationService_RollbackApplicationRollout_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_ApplicationService_RollbackApplicationRollout_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + mux.Handle("DELETE", pattern_ApplicationService_DeleteResource_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -2561,6 +2724,29 @@ func RegisterApplicationServiceHandlerServer(ctx context.Context, mux *runtime.S }) + mux.Handle("POST", pattern_ApplicationService_ValidateSrcAndDst_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_ApplicationService_ValidateSrcAndDst_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_ApplicationService_ValidateSrcAndDst_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + mux.Handle("GET", pattern_ApplicationService_PodLogs_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { err := status.Error(codes.Unimplemented, "streaming calls are not yet supported in the in-process transport") _, outboundMarshaler := runtime.MarshalerForRequest(mux, req) @@ -2621,6 +2807,29 @@ func RegisterApplicationServiceHandlerServer(ctx context.Context, mux *runtime.S }) + mux.Handle("GET", pattern_ApplicationService_GetChangeRevision_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_ApplicationService_GetChangeRevision_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_ApplicationService_GetChangeRevision_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + return nil } @@ -3142,6 +3351,26 @@ func RegisterApplicationServiceHandlerClient(ctx context.Context, mux *runtime.S }) + mux.Handle("POST", pattern_ApplicationService_RollbackApplicationRollout_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_ApplicationService_RollbackApplicationRollout_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_ApplicationService_RollbackApplicationRollout_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + mux.Handle("DELETE", pattern_ApplicationService_DeleteResource_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -3162,6 +3391,26 @@ func RegisterApplicationServiceHandlerClient(ctx context.Context, mux *runtime.S }) + mux.Handle("POST", pattern_ApplicationService_ValidateSrcAndDst_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_ApplicationService_ValidateSrcAndDst_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_ApplicationService_ValidateSrcAndDst_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + mux.Handle("GET", pattern_ApplicationService_PodLogs_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -3242,6 +3491,26 @@ func RegisterApplicationServiceHandlerClient(ctx context.Context, mux *runtime.S }) + mux.Handle("GET", pattern_ApplicationService_GetChangeRevision_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_ApplicationService_GetChangeRevision_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_ApplicationService_GetChangeRevision_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + return nil } @@ -3294,8 +3563,12 @@ var ( pattern_ApplicationService_RunResourceAction_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3, 2, 4, 2, 5}, []string{"api", "v1", "applications", "name", "resource", "actions"}, "", runtime.AssumeColonVerbOpt(true))) + pattern_ApplicationService_RollbackApplicationRollout_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3, 2, 4}, []string{"api", "v1", "applications", "name", "rollout-rollback"}, "", runtime.AssumeColonVerbOpt(true))) + pattern_ApplicationService_DeleteResource_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3, 2, 4}, []string{"api", "v1", "applications", "name", "resource"}, "", runtime.AssumeColonVerbOpt(true))) + pattern_ApplicationService_ValidateSrcAndDst_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "v1", "application-validate"}, "", runtime.AssumeColonVerbOpt(true))) + pattern_ApplicationService_PodLogs_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3, 2, 4, 1, 0, 4, 1, 5, 5, 2, 6}, []string{"api", "v1", "applications", "name", "pods", "podName", "logs"}, "", runtime.AssumeColonVerbOpt(true))) pattern_ApplicationService_PodLogs_1 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3, 2, 4}, []string{"api", "v1", "applications", "name", "logs"}, "", runtime.AssumeColonVerbOpt(true))) @@ -3303,6 +3576,8 @@ var ( pattern_ApplicationService_ListLinks_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3, 2, 4}, []string{"api", "v1", "applications", "name", "links"}, "", runtime.AssumeColonVerbOpt(true))) pattern_ApplicationService_ListResourceLinks_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3, 2, 4, 2, 5}, []string{"api", "v1", "applications", "name", "resource", "links"}, "", runtime.AssumeColonVerbOpt(true))) + + pattern_ApplicationService_GetChangeRevision_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"api", "v1", "application", "changeRevision"}, "", runtime.AssumeColonVerbOpt(true))) ) var ( @@ -3354,8 +3629,12 @@ var ( forward_ApplicationService_RunResourceAction_0 = runtime.ForwardResponseMessage + forward_ApplicationService_RollbackApplicationRollout_0 = runtime.ForwardResponseMessage + forward_ApplicationService_DeleteResource_0 = runtime.ForwardResponseMessage + forward_ApplicationService_ValidateSrcAndDst_0 = runtime.ForwardResponseMessage + forward_ApplicationService_PodLogs_0 = runtime.ForwardResponseStream forward_ApplicationService_PodLogs_1 = runtime.ForwardResponseStream @@ -3363,4 +3642,6 @@ var ( forward_ApplicationService_ListLinks_0 = runtime.ForwardResponseMessage forward_ApplicationService_ListResourceLinks_0 = runtime.ForwardResponseMessage + + forward_ApplicationService_GetChangeRevision_0 = runtime.ForwardResponseMessage ) diff --git a/pkg/apiclient/events/events.pb.go b/pkg/apiclient/events/events.pb.go new file mode 100644 index 0000000000000..9abdc40a779b8 --- /dev/null +++ b/pkg/apiclient/events/events.pb.go @@ -0,0 +1,4115 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: server/application/events.proto + +// Events Service +// +// Events Service API provides a generic event-source that allows +// listening for argo-cd events natively from argo-events. + +package events + +import ( + fmt "fmt" + _ "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + _ "github.com/gogo/protobuf/gogoproto" + github_com_gogo_protobuf_proto "github.com/gogo/protobuf/proto" + proto "github.com/gogo/protobuf/proto" + _ "google.golang.org/genproto/googleapis/api/annotations" + io "io" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + math "math" + math_bits "math/bits" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +type EventSource struct { + // The event source name. + Name *string `protobuf:"bytes,1,req,name=name" json:"name,omitempty"` + // The event source configuration value. + Config []byte `protobuf:"bytes,2,opt,name=config" json:"config,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *EventSource) Reset() { *m = EventSource{} } +func (m *EventSource) String() string { return proto.CompactTextString(m) } +func (*EventSource) ProtoMessage() {} +func (*EventSource) Descriptor() ([]byte, []int) { + return fileDescriptor_3ad9267ec62b112f, []int{0} +} +func (m *EventSource) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *EventSource) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_EventSource.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *EventSource) XXX_Merge(src proto.Message) { + xxx_messageInfo_EventSource.Merge(m, src) +} +func (m *EventSource) XXX_Size() int { + return m.Size() +} +func (m *EventSource) XXX_DiscardUnknown() { + xxx_messageInfo_EventSource.DiscardUnknown(m) +} + +var xxx_messageInfo_EventSource proto.InternalMessageInfo + +func (m *EventSource) GetName() string { + if m != nil && m.Name != nil { + return *m.Name + } + return "" +} + +func (m *EventSource) GetConfig() []byte { + if m != nil { + return m.Config + } + return nil +} + +// * +// Represents an event +type Event struct { + // The event source name. + Name *string `protobuf:"bytes,1,req,name=name" json:"name,omitempty"` + // The event payload. + Payload []byte `protobuf:"bytes,2,req,name=payload" json:"payload,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Event) Reset() { *m = Event{} } +func (m *Event) String() string { return proto.CompactTextString(m) } +func (*Event) ProtoMessage() {} +func (*Event) Descriptor() ([]byte, []int) { + return fileDescriptor_3ad9267ec62b112f, []int{1} +} +func (m *Event) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Event) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Event.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *Event) XXX_Merge(src proto.Message) { + xxx_messageInfo_Event.Merge(m, src) +} +func (m *Event) XXX_Size() int { + return m.Size() +} +func (m *Event) XXX_DiscardUnknown() { + xxx_messageInfo_Event.DiscardUnknown(m) +} + +var xxx_messageInfo_Event proto.InternalMessageInfo + +func (m *Event) GetName() string { + if m != nil && m.Name != nil { + return *m.Name + } + return "" +} + +func (m *Event) GetPayload() []byte { + if m != nil { + return m.Payload + } + return nil +} + +// * +// The actual object that will be send +// with each event. +type EventPayload struct { + // The timestamp of the event + Timestamp string `protobuf:"bytes,1,req,name=timestamp" json:"timestamp"` + // The object that the event is about + Object []byte `protobuf:"bytes,2,req,name=object" json:"object,omitempty"` + // The object source information + Source *ObjectSource `protobuf:"bytes,3,req,name=source" json:"source,omitempty"` + // The errors of this object + Errors []*ObjectError `protobuf:"bytes,4,rep,name=errors" json:"errors,omitempty"` + // A version of the application and its dependencies + AppVersions *ApplicationVersions `protobuf:"bytes,5,opt,name=appVersions" json:"appVersions,omitempty"` + // A version of codefresh runtime + RuntimeVersion string `protobuf:"bytes,6,req,name=runtimeVersion" json:"runtimeVersion"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *EventPayload) Reset() { *m = EventPayload{} } +func (m *EventPayload) String() string { return proto.CompactTextString(m) } +func (*EventPayload) ProtoMessage() {} +func (*EventPayload) Descriptor() ([]byte, []int) { + return fileDescriptor_3ad9267ec62b112f, []int{2} +} +func (m *EventPayload) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *EventPayload) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_EventPayload.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *EventPayload) XXX_Merge(src proto.Message) { + xxx_messageInfo_EventPayload.Merge(m, src) +} +func (m *EventPayload) XXX_Size() int { + return m.Size() +} +func (m *EventPayload) XXX_DiscardUnknown() { + xxx_messageInfo_EventPayload.DiscardUnknown(m) +} + +var xxx_messageInfo_EventPayload proto.InternalMessageInfo + +func (m *EventPayload) GetTimestamp() string { + if m != nil { + return m.Timestamp + } + return "" +} + +func (m *EventPayload) GetObject() []byte { + if m != nil { + return m.Object + } + return nil +} + +func (m *EventPayload) GetSource() *ObjectSource { + if m != nil { + return m.Source + } + return nil +} + +func (m *EventPayload) GetErrors() []*ObjectError { + if m != nil { + return m.Errors + } + return nil +} + +func (m *EventPayload) GetAppVersions() *ApplicationVersions { + if m != nil { + return m.AppVersions + } + return nil +} + +func (m *EventPayload) GetRuntimeVersion() string { + if m != nil { + return m.RuntimeVersion + } + return "" +} + +// * +// Holds information about the object source +type ObjectSource struct { + DesiredManifest string `protobuf:"bytes,1,opt,name=desiredManifest" json:"desiredManifest"` + ActualManifest string `protobuf:"bytes,2,opt,name=actualManifest" json:"actualManifest"` + GitManifest string `protobuf:"bytes,3,opt,name=gitManifest" json:"gitManifest"` + RepoURL string `protobuf:"bytes,4,opt,name=repoURL" json:"repoURL"` + Path string `protobuf:"bytes,5,opt,name=path" json:"path"` + Revision string `protobuf:"bytes,6,opt,name=revision" json:"revision"` + CommitMessage string `protobuf:"bytes,7,opt,name=commitMessage" json:"commitMessage"` + CommitAuthor string `protobuf:"bytes,8,opt,name=commitAuthor" json:"commitAuthor"` + CommitDate *v1.Time `protobuf:"bytes,9,opt,name=commitDate" json:"commitDate,omitempty"` + AppName string `protobuf:"bytes,10,opt,name=appName" json:"appName"` + AppLabels map[string]string `protobuf:"bytes,11,rep,name=appLabels" json:"appLabels" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + SyncStatus string `protobuf:"bytes,12,opt,name=syncStatus" json:"syncStatus"` + SyncStartedAt v1.Time `protobuf:"bytes,13,opt,name=syncStartedAt" json:"syncStartedAt"` + SyncFinishedAt *v1.Time `protobuf:"bytes,14,opt,name=syncFinishedAt" json:"syncFinishedAt,omitempty"` + HealthStatus *string `protobuf:"bytes,15,opt,name=healthStatus" json:"healthStatus,omitempty"` + HealthMessage *string `protobuf:"bytes,16,opt,name=healthMessage" json:"healthMessage,omitempty"` + Cluster string `protobuf:"bytes,17,opt,name=cluster" json:"cluster"` + HistoryId int64 `protobuf:"varint,18,opt,name=historyId" json:"historyId"` + OperationSyncRevision string `protobuf:"bytes,19,opt,name=operationSyncRevision" json:"operationSyncRevision"` + AppUID string `protobuf:"bytes,20,opt,name=appUID" json:"appUID"` + AppNamespace string `protobuf:"bytes,21,opt,name=appNamespace" json:"appNamespace"` + AppInstanceLabelKey string `protobuf:"bytes,22,opt,name=appInstanceLabelKey" json:"appInstanceLabelKey"` + TrackingMethod string `protobuf:"bytes,23,opt,name=trackingMethod" json:"trackingMethod"` + Revisions []string `protobuf:"bytes,24,rep,name=revisions" json:"revisions,omitempty"` + OperationSyncRevisions []string `protobuf:"bytes,25,rep,name=operationSyncRevisions" json:"operationSyncRevisions,omitempty"` + ClusterName *string `protobuf:"bytes,26,opt,name=clusterName" json:"clusterName,omitempty"` + AppMultiSourced bool `protobuf:"varint,27,req,name=appMultiSourced" json:"appMultiSourced"` + AppSourceIdx int32 `protobuf:"varint,28,req,name=appSourceIdx" json:"appSourceIdx"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ObjectSource) Reset() { *m = ObjectSource{} } +func (m *ObjectSource) String() string { return proto.CompactTextString(m) } +func (*ObjectSource) ProtoMessage() {} +func (*ObjectSource) Descriptor() ([]byte, []int) { + return fileDescriptor_3ad9267ec62b112f, []int{3} +} +func (m *ObjectSource) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ObjectSource) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ObjectSource.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *ObjectSource) XXX_Merge(src proto.Message) { + xxx_messageInfo_ObjectSource.Merge(m, src) +} +func (m *ObjectSource) XXX_Size() int { + return m.Size() +} +func (m *ObjectSource) XXX_DiscardUnknown() { + xxx_messageInfo_ObjectSource.DiscardUnknown(m) +} + +var xxx_messageInfo_ObjectSource proto.InternalMessageInfo + +func (m *ObjectSource) GetDesiredManifest() string { + if m != nil { + return m.DesiredManifest + } + return "" +} + +func (m *ObjectSource) GetActualManifest() string { + if m != nil { + return m.ActualManifest + } + return "" +} + +func (m *ObjectSource) GetGitManifest() string { + if m != nil { + return m.GitManifest + } + return "" +} + +func (m *ObjectSource) GetRepoURL() string { + if m != nil { + return m.RepoURL + } + return "" +} + +func (m *ObjectSource) GetPath() string { + if m != nil { + return m.Path + } + return "" +} + +func (m *ObjectSource) GetRevision() string { + if m != nil { + return m.Revision + } + return "" +} + +func (m *ObjectSource) GetCommitMessage() string { + if m != nil { + return m.CommitMessage + } + return "" +} + +func (m *ObjectSource) GetCommitAuthor() string { + if m != nil { + return m.CommitAuthor + } + return "" +} + +func (m *ObjectSource) GetCommitDate() *v1.Time { + if m != nil { + return m.CommitDate + } + return nil +} + +func (m *ObjectSource) GetAppName() string { + if m != nil { + return m.AppName + } + return "" +} + +func (m *ObjectSource) GetAppLabels() map[string]string { + if m != nil { + return m.AppLabels + } + return nil +} + +func (m *ObjectSource) GetSyncStatus() string { + if m != nil { + return m.SyncStatus + } + return "" +} + +func (m *ObjectSource) GetSyncStartedAt() v1.Time { + if m != nil { + return m.SyncStartedAt + } + return v1.Time{} +} + +func (m *ObjectSource) GetSyncFinishedAt() *v1.Time { + if m != nil { + return m.SyncFinishedAt + } + return nil +} + +func (m *ObjectSource) GetHealthStatus() string { + if m != nil && m.HealthStatus != nil { + return *m.HealthStatus + } + return "" +} + +func (m *ObjectSource) GetHealthMessage() string { + if m != nil && m.HealthMessage != nil { + return *m.HealthMessage + } + return "" +} + +func (m *ObjectSource) GetCluster() string { + if m != nil { + return m.Cluster + } + return "" +} + +func (m *ObjectSource) GetHistoryId() int64 { + if m != nil { + return m.HistoryId + } + return 0 +} + +func (m *ObjectSource) GetOperationSyncRevision() string { + if m != nil { + return m.OperationSyncRevision + } + return "" +} + +func (m *ObjectSource) GetAppUID() string { + if m != nil { + return m.AppUID + } + return "" +} + +func (m *ObjectSource) GetAppNamespace() string { + if m != nil { + return m.AppNamespace + } + return "" +} + +func (m *ObjectSource) GetAppInstanceLabelKey() string { + if m != nil { + return m.AppInstanceLabelKey + } + return "" +} + +func (m *ObjectSource) GetTrackingMethod() string { + if m != nil { + return m.TrackingMethod + } + return "" +} + +func (m *ObjectSource) GetRevisions() []string { + if m != nil { + return m.Revisions + } + return nil +} + +func (m *ObjectSource) GetOperationSyncRevisions() []string { + if m != nil { + return m.OperationSyncRevisions + } + return nil +} + +func (m *ObjectSource) GetClusterName() string { + if m != nil && m.ClusterName != nil { + return *m.ClusterName + } + return "" +} + +func (m *ObjectSource) GetAppMultiSourced() bool { + if m != nil { + return m.AppMultiSourced + } + return false +} + +func (m *ObjectSource) GetAppSourceIdx() int32 { + if m != nil { + return m.AppSourceIdx + } + return 0 +} + +// * +// Holds error information; present only when error sent with application but not resource itself +type ObjectError struct { + Type string `protobuf:"bytes,1,opt,name=type" json:"type"` + Level string `protobuf:"bytes,2,opt,name=level" json:"level"` + Message string `protobuf:"bytes,3,opt,name=message" json:"message"` + LastSeen v1.Time `protobuf:"bytes,4,opt,name=lastSeen" json:"lastSeen"` + SourceReference *ErrorSourceReference `protobuf:"bytes,5,opt,name=sourceReference" json:"sourceReference,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ObjectError) Reset() { *m = ObjectError{} } +func (m *ObjectError) String() string { return proto.CompactTextString(m) } +func (*ObjectError) ProtoMessage() {} +func (*ObjectError) Descriptor() ([]byte, []int) { + return fileDescriptor_3ad9267ec62b112f, []int{4} +} +func (m *ObjectError) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ObjectError) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ObjectError.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *ObjectError) XXX_Merge(src proto.Message) { + xxx_messageInfo_ObjectError.Merge(m, src) +} +func (m *ObjectError) XXX_Size() int { + return m.Size() +} +func (m *ObjectError) XXX_DiscardUnknown() { + xxx_messageInfo_ObjectError.DiscardUnknown(m) +} + +var xxx_messageInfo_ObjectError proto.InternalMessageInfo + +func (m *ObjectError) GetType() string { + if m != nil { + return m.Type + } + return "" +} + +func (m *ObjectError) GetLevel() string { + if m != nil { + return m.Level + } + return "" +} + +func (m *ObjectError) GetMessage() string { + if m != nil { + return m.Message + } + return "" +} + +func (m *ObjectError) GetLastSeen() v1.Time { + if m != nil { + return m.LastSeen + } + return v1.Time{} +} + +func (m *ObjectError) GetSourceReference() *ErrorSourceReference { + if m != nil { + return m.SourceReference + } + return nil +} + +// * +// Holds application resource metadata to which the error related +type ErrorSourceReference struct { + Group string `protobuf:"bytes,1,opt,name=group" json:"group"` + Version string `protobuf:"bytes,2,opt,name=version" json:"version"` + Kind string `protobuf:"bytes,3,req,name=kind" json:"kind"` + Name string `protobuf:"bytes,4,req,name=name" json:"name"` + Namespace string `protobuf:"bytes,5,opt,name=namespace" json:"namespace"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ErrorSourceReference) Reset() { *m = ErrorSourceReference{} } +func (m *ErrorSourceReference) String() string { return proto.CompactTextString(m) } +func (*ErrorSourceReference) ProtoMessage() {} +func (*ErrorSourceReference) Descriptor() ([]byte, []int) { + return fileDescriptor_3ad9267ec62b112f, []int{5} +} +func (m *ErrorSourceReference) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ErrorSourceReference) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ErrorSourceReference.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *ErrorSourceReference) XXX_Merge(src proto.Message) { + xxx_messageInfo_ErrorSourceReference.Merge(m, src) +} +func (m *ErrorSourceReference) XXX_Size() int { + return m.Size() +} +func (m *ErrorSourceReference) XXX_DiscardUnknown() { + xxx_messageInfo_ErrorSourceReference.DiscardUnknown(m) +} + +var xxx_messageInfo_ErrorSourceReference proto.InternalMessageInfo + +func (m *ErrorSourceReference) GetGroup() string { + if m != nil { + return m.Group + } + return "" +} + +func (m *ErrorSourceReference) GetVersion() string { + if m != nil { + return m.Version + } + return "" +} + +func (m *ErrorSourceReference) GetKind() string { + if m != nil { + return m.Kind + } + return "" +} + +func (m *ErrorSourceReference) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *ErrorSourceReference) GetNamespace() string { + if m != nil { + return m.Namespace + } + return "" +} + +type Dependencies struct { + // Content of Chart.lock + Lock *string `protobuf:"bytes,1,opt,name=lock" json:"lock,omitempty"` + // Content of Chart.yaml + Deps *string `protobuf:"bytes,2,opt,name=deps" json:"deps,omitempty"` + // Content of requirements.yaml + Requirements *string `protobuf:"bytes,3,opt,name=requirements" json:"requirements,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Dependencies) Reset() { *m = Dependencies{} } +func (m *Dependencies) String() string { return proto.CompactTextString(m) } +func (*Dependencies) ProtoMessage() {} +func (*Dependencies) Descriptor() ([]byte, []int) { + return fileDescriptor_3ad9267ec62b112f, []int{6} +} +func (m *Dependencies) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Dependencies) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Dependencies.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *Dependencies) XXX_Merge(src proto.Message) { + xxx_messageInfo_Dependencies.Merge(m, src) +} +func (m *Dependencies) XXX_Size() int { + return m.Size() +} +func (m *Dependencies) XXX_DiscardUnknown() { + xxx_messageInfo_Dependencies.DiscardUnknown(m) +} + +var xxx_messageInfo_Dependencies proto.InternalMessageInfo + +func (m *Dependencies) GetLock() string { + if m != nil && m.Lock != nil { + return *m.Lock + } + return "" +} + +func (m *Dependencies) GetDeps() string { + if m != nil && m.Deps != nil { + return *m.Deps + } + return "" +} + +func (m *Dependencies) GetRequirements() string { + if m != nil && m.Requirements != nil { + return *m.Requirements + } + return "" +} + +type ApplicationVersions struct { + // Application version presented by single value + AppVersion *string `protobuf:"bytes,1,opt,name=appVersion" json:"appVersion,omitempty"` + // Yaml content of dependencies + Dependencies *Dependencies `protobuf:"bytes,2,opt,name=dependencies" json:"dependencies,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ApplicationVersions) Reset() { *m = ApplicationVersions{} } +func (m *ApplicationVersions) String() string { return proto.CompactTextString(m) } +func (*ApplicationVersions) ProtoMessage() {} +func (*ApplicationVersions) Descriptor() ([]byte, []int) { + return fileDescriptor_3ad9267ec62b112f, []int{7} +} +func (m *ApplicationVersions) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ApplicationVersions) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ApplicationVersions.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *ApplicationVersions) XXX_Merge(src proto.Message) { + xxx_messageInfo_ApplicationVersions.Merge(m, src) +} +func (m *ApplicationVersions) XXX_Size() int { + return m.Size() +} +func (m *ApplicationVersions) XXX_DiscardUnknown() { + xxx_messageInfo_ApplicationVersions.DiscardUnknown(m) +} + +var xxx_messageInfo_ApplicationVersions proto.InternalMessageInfo + +func (m *ApplicationVersions) GetAppVersion() string { + if m != nil && m.AppVersion != nil { + return *m.AppVersion + } + return "" +} + +func (m *ApplicationVersions) GetDependencies() *Dependencies { + if m != nil { + return m.Dependencies + } + return nil +} + +func init() { + proto.RegisterType((*EventSource)(nil), "generic.EventSource") + proto.RegisterType((*Event)(nil), "generic.Event") + proto.RegisterType((*EventPayload)(nil), "generic.EventPayload") + proto.RegisterType((*ObjectSource)(nil), "generic.ObjectSource") + proto.RegisterMapType((map[string]string)(nil), "generic.ObjectSource.AppLabelsEntry") + proto.RegisterType((*ObjectError)(nil), "generic.ObjectError") + proto.RegisterType((*ErrorSourceReference)(nil), "generic.ErrorSourceReference") + proto.RegisterType((*Dependencies)(nil), "generic.Dependencies") + proto.RegisterType((*ApplicationVersions)(nil), "generic.ApplicationVersions") +} + +func init() { proto.RegisterFile("server/application/events.proto", fileDescriptor_3ad9267ec62b112f) } + +var fileDescriptor_3ad9267ec62b112f = []byte{ + // 1125 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x56, 0xdd, 0x8e, 0x1b, 0xb5, + 0x17, 0xff, 0x27, 0xfb, 0x99, 0x93, 0xec, 0xb6, 0x7f, 0x77, 0x5b, 0xcc, 0xb2, 0x6c, 0xa3, 0xa8, + 0x42, 0x51, 0xd5, 0x26, 0xea, 0x02, 0x55, 0x5b, 0x21, 0xa4, 0xad, 0x5a, 0x60, 0x61, 0x17, 0xd0, + 0x2c, 0xed, 0x45, 0xef, 0xdc, 0x99, 0xd3, 0x89, 0x9b, 0x89, 0x6d, 0x6c, 0x27, 0x22, 0x0f, 0xc2, + 0x4b, 0xf0, 0x24, 0xbd, 0xe4, 0x8a, 0x4b, 0x84, 0xfa, 0x18, 0x5c, 0x21, 0x7b, 0x3c, 0x89, 0x27, + 0x04, 0x89, 0x72, 0x67, 0xff, 0xce, 0xef, 0x1c, 0xfb, 0x7c, 0xda, 0x70, 0xd3, 0xa0, 0x9e, 0xa1, + 0x1e, 0x32, 0xa5, 0x0a, 0x9e, 0x32, 0xcb, 0xa5, 0x18, 0xe2, 0x0c, 0x85, 0x35, 0x03, 0xa5, 0xa5, + 0x95, 0x64, 0x27, 0x47, 0x81, 0x9a, 0xa7, 0x87, 0xe7, 0x39, 0xb7, 0xa3, 0xe9, 0xcb, 0x41, 0x2a, + 0x27, 0x43, 0xa6, 0x73, 0xa9, 0xb4, 0x7c, 0xed, 0x17, 0x77, 0xd3, 0x6c, 0x38, 0x3b, 0x19, 0xaa, + 0x71, 0x3e, 0x64, 0x8a, 0x9b, 0x9a, 0xa9, 0xd9, 0x3d, 0x56, 0xa8, 0x11, 0xbb, 0x37, 0xf4, 0x56, + 0x98, 0xc5, 0xac, 0x34, 0x7b, 0xf8, 0xc9, 0xf8, 0x81, 0x19, 0x70, 0xe9, 0x34, 0x26, 0x2c, 0x1d, + 0x71, 0x81, 0x7a, 0xbe, 0x34, 0x31, 0x41, 0xcb, 0x86, 0xb3, 0xbf, 0x6b, 0x1d, 0xe4, 0xd2, 0x1f, + 0x6c, 0xe5, 0xd0, 0xad, 0x02, 0x7a, 0x94, 0x4b, 0x99, 0x17, 0xe8, 0x54, 0x87, 0x4c, 0x08, 0x69, + 0xfd, 0xd9, 0xc1, 0x81, 0xde, 0x43, 0x68, 0x3f, 0x75, 0x0e, 0x5d, 0xca, 0xa9, 0x4e, 0x91, 0x10, + 0xd8, 0x14, 0x6c, 0x82, 0xb4, 0xd1, 0x6d, 0xf6, 0x5b, 0x89, 0x5f, 0x93, 0x1b, 0xb0, 0x9d, 0x4a, + 0xf1, 0x8a, 0xe7, 0xb4, 0xd9, 0x6d, 0xf4, 0x3b, 0x49, 0xd8, 0xf5, 0x3e, 0x85, 0x2d, 0xaf, 0xba, + 0x56, 0x89, 0xc2, 0x8e, 0x62, 0xf3, 0x42, 0xb2, 0x8c, 0x36, 0xbb, 0xcd, 0x7e, 0x27, 0xa9, 0xb6, + 0xbd, 0x9f, 0x9b, 0xd0, 0xf1, 0x7a, 0xdf, 0x97, 0x00, 0xe9, 0x41, 0xcb, 0xf2, 0x09, 0x1a, 0xcb, + 0x26, 0xaa, 0xb4, 0xf1, 0x78, 0xf3, 0xcd, 0xef, 0x37, 0xff, 0x97, 0x2c, 0x61, 0x77, 0x07, 0xf9, + 0xf2, 0x35, 0xa6, 0x36, 0x58, 0x0b, 0x3b, 0x72, 0x17, 0xb6, 0x8d, 0xbf, 0x39, 0xdd, 0xe8, 0x36, + 0xfb, 0xed, 0x93, 0xeb, 0x83, 0x90, 0x90, 0xc1, 0x77, 0x9e, 0x50, 0xba, 0x95, 0x04, 0x12, 0xb9, + 0x03, 0xdb, 0xa8, 0xb5, 0xd4, 0x86, 0x6e, 0x76, 0x37, 0xfa, 0xed, 0x93, 0x83, 0x15, 0xfa, 0x53, + 0x27, 0x4c, 0x02, 0x87, 0x7c, 0x0e, 0x6d, 0xa6, 0xd4, 0x73, 0xd4, 0xc6, 0x05, 0x8c, 0x6e, 0x75, + 0x1b, 0xfd, 0xf6, 0xc9, 0xd1, 0x42, 0xe5, 0x74, 0x99, 0xc9, 0x8a, 0x93, 0xc4, 0x0a, 0xe4, 0x0e, + 0xec, 0xeb, 0xa9, 0x70, 0x4e, 0x04, 0x88, 0x6e, 0x47, 0xde, 0xad, 0xc8, 0x7a, 0xbf, 0x01, 0x74, + 0xe2, 0x4b, 0x93, 0x01, 0x5c, 0xc9, 0xd0, 0x70, 0x8d, 0xd9, 0x05, 0x13, 0xfc, 0x15, 0x1a, 0x4b, + 0x1b, 0xdd, 0xc6, 0x42, 0x7f, 0x55, 0xe8, 0x8e, 0x63, 0xa9, 0x9d, 0xb2, 0x62, 0x41, 0x6f, 0x46, + 0xf4, 0x15, 0x19, 0xf9, 0x08, 0xda, 0x39, 0xb7, 0x0b, 0xea, 0x46, 0x44, 0x8d, 0x05, 0xe4, 0x18, + 0x76, 0x34, 0x2a, 0xf9, 0x2c, 0x39, 0xa7, 0x9b, 0x11, 0xa7, 0x02, 0x09, 0x85, 0x4d, 0xc5, 0xec, + 0xc8, 0x47, 0xa7, 0x12, 0x7a, 0x84, 0x74, 0x61, 0x57, 0xe3, 0x8c, 0x07, 0xc7, 0x97, 0xd2, 0x05, + 0x4a, 0x6e, 0xc3, 0x5e, 0x2a, 0x27, 0x13, 0x6e, 0x2f, 0xd0, 0x18, 0x96, 0x23, 0xdd, 0x89, 0x68, + 0x75, 0x11, 0xe9, 0x43, 0xa7, 0x04, 0x4e, 0xa7, 0x76, 0x24, 0x35, 0xdd, 0x8d, 0xa8, 0x35, 0x09, + 0xf9, 0x1a, 0xa0, 0xdc, 0x3f, 0x61, 0x16, 0x69, 0xcb, 0x67, 0xed, 0xf6, 0xa0, 0xec, 0xa8, 0x41, + 0xdc, 0x51, 0x03, 0x35, 0xce, 0x1d, 0x60, 0x06, 0xae, 0xa3, 0x06, 0xb3, 0x7b, 0x83, 0x1f, 0xf8, + 0x04, 0x93, 0x48, 0xdb, 0x79, 0xcf, 0x94, 0xfa, 0xd6, 0x55, 0x37, 0xc4, 0xde, 0x07, 0x90, 0x7c, + 0x05, 0x2d, 0xa6, 0xd4, 0x39, 0x7b, 0x89, 0x85, 0xa1, 0x6d, 0x5f, 0x53, 0xb7, 0xd6, 0x96, 0xa0, + 0xab, 0x96, 0x92, 0xf6, 0x54, 0x58, 0x3d, 0xaf, 0x2a, 0x7c, 0xa1, 0x4c, 0x6e, 0x01, 0x98, 0xb9, + 0x48, 0x2f, 0x2d, 0xb3, 0x53, 0x43, 0x3b, 0xd1, 0x61, 0x11, 0x4e, 0x9e, 0xc3, 0x5e, 0xd8, 0x69, + 0x8b, 0xd9, 0xa9, 0xa5, 0x7b, 0xef, 0xea, 0x5e, 0x15, 0xdd, 0x9a, 0x19, 0x92, 0xc0, 0xbe, 0x03, + 0xbe, 0xe0, 0x82, 0x9b, 0x91, 0x37, 0xbc, 0xff, 0xce, 0x71, 0x5b, 0xb1, 0x40, 0x7a, 0xd0, 0x19, + 0x21, 0x2b, 0xec, 0x28, 0xf8, 0x74, 0xc5, 0xf9, 0x94, 0xd4, 0x30, 0x72, 0x0b, 0xf6, 0xca, 0x7d, + 0x55, 0x01, 0x57, 0x3d, 0xa9, 0x0e, 0xba, 0x2c, 0xa4, 0xc5, 0xd4, 0x58, 0xd4, 0xf4, 0xff, 0x71, + 0x16, 0x02, 0xe8, 0x26, 0xc8, 0x88, 0x1b, 0x2b, 0xf5, 0xfc, 0x2c, 0xa3, 0xa4, 0xdb, 0xe8, 0x6f, + 0x54, 0xf1, 0x5d, 0xc0, 0xe4, 0x11, 0x5c, 0x97, 0xca, 0x8d, 0x4b, 0x2e, 0xc5, 0xe5, 0x5c, 0xa4, + 0x49, 0x55, 0x9a, 0xd7, 0x22, 0x8b, 0xeb, 0x29, 0xe4, 0x08, 0xb6, 0x99, 0x52, 0xcf, 0xce, 0x9e, + 0xd0, 0x83, 0x88, 0x1c, 0x30, 0x57, 0x99, 0xa1, 0x1c, 0x8c, 0x62, 0x29, 0xd2, 0xeb, 0x71, 0x65, + 0xc6, 0x12, 0x72, 0x1f, 0xae, 0x31, 0xa5, 0xce, 0x84, 0xb1, 0x4c, 0xa4, 0xe8, 0x13, 0xff, 0x0d, + 0xce, 0xe9, 0x8d, 0x48, 0x61, 0x1d, 0xc1, 0x75, 0xb6, 0xd5, 0x2c, 0x1d, 0x73, 0x91, 0x5f, 0xa0, + 0x1d, 0xc9, 0x8c, 0xbe, 0x17, 0x77, 0x76, 0x5d, 0x46, 0x8e, 0xa0, 0x55, 0x75, 0x98, 0xa1, 0xb4, + 0xbb, 0xd1, 0x6f, 0x25, 0x4b, 0x80, 0xdc, 0x87, 0x1b, 0x6b, 0x9d, 0x34, 0xf4, 0x7d, 0x4f, 0xfd, + 0x07, 0x29, 0xe9, 0x42, 0x3b, 0x84, 0xdb, 0x77, 0xc3, 0xa1, 0xcf, 0x53, 0x0c, 0xb9, 0x79, 0xc5, + 0x94, 0xba, 0x98, 0x16, 0x96, 0x97, 0x35, 0x9f, 0xd1, 0x0f, 0xba, 0xcd, 0xfe, 0x6e, 0x35, 0xaf, + 0x56, 0x84, 0x21, 0x6e, 0xe5, 0xee, 0x2c, 0xfb, 0x89, 0x1e, 0x75, 0x9b, 0xfd, 0xad, 0x28, 0x6e, + 0x0b, 0xc9, 0xe1, 0x67, 0xb0, 0x5f, 0x6f, 0x1f, 0x72, 0x15, 0x36, 0xc6, 0x38, 0x2f, 0xe7, 0x61, + 0xe2, 0x96, 0xe4, 0x00, 0xb6, 0x66, 0xac, 0x98, 0x62, 0x39, 0xf4, 0x92, 0x72, 0xf3, 0xa8, 0xf9, + 0xa0, 0xd1, 0xfb, 0xb3, 0x01, 0xed, 0x68, 0xbc, 0xbb, 0x89, 0x65, 0xe7, 0x0a, 0x6b, 0xc3, 0xd4, + 0x23, 0xe4, 0x10, 0xb6, 0x0a, 0x9c, 0x61, 0x51, 0x1b, 0x9c, 0x25, 0xe4, 0x6a, 0x70, 0x12, 0x6a, + 0x34, 0x9e, 0x95, 0x15, 0x48, 0xce, 0x61, 0xb7, 0x60, 0xc6, 0x5e, 0x22, 0x0a, 0x3f, 0x28, 0xff, + 0x4b, 0x53, 0x2e, 0x2c, 0x90, 0x2f, 0xe1, 0x4a, 0xf9, 0x64, 0x25, 0xf8, 0x0a, 0x35, 0x8a, 0x14, + 0xc3, 0xf3, 0xf3, 0xe1, 0x62, 0xba, 0x78, 0x67, 0x2e, 0xeb, 0xa4, 0x64, 0x55, 0xab, 0xf7, 0x4b, + 0x03, 0x0e, 0xd6, 0x31, 0x9d, 0xaf, 0xb9, 0x96, 0x53, 0x55, 0x0b, 0x43, 0x09, 0x39, 0x5f, 0x67, + 0xe1, 0xc5, 0x8a, 0x23, 0x51, 0x81, 0x2e, 0x82, 0x63, 0x2e, 0x32, 0xff, 0xe6, 0x2e, 0x22, 0xe8, + 0x10, 0x27, 0xf1, 0x5f, 0x81, 0xcd, 0x58, 0xe2, 0x3f, 0x04, 0x3d, 0x68, 0x89, 0x45, 0x8b, 0xc4, + 0x8f, 0xc5, 0x12, 0xee, 0xbd, 0x80, 0xce, 0x13, 0x54, 0x28, 0x32, 0x14, 0x29, 0x47, 0xe3, 0x3e, + 0x16, 0x85, 0x4c, 0xc7, 0x21, 0xcd, 0x7e, 0xed, 0xb0, 0x0c, 0x95, 0x09, 0x69, 0xf6, 0x6b, 0x37, + 0x69, 0x34, 0xfe, 0x38, 0xe5, 0x1a, 0x27, 0xee, 0x6f, 0x56, 0x26, 0x28, 0xa9, 0x61, 0x3d, 0x05, + 0xd7, 0xd6, 0x3c, 0xd8, 0xe4, 0x18, 0x60, 0xf9, 0x64, 0x87, 0x83, 0x22, 0x84, 0x3c, 0x84, 0x4e, + 0x16, 0x5d, 0xc9, 0x1f, 0x1b, 0x7f, 0x33, 0xe2, 0xfb, 0x26, 0x35, 0xea, 0xe3, 0xd3, 0x37, 0x6f, + 0x8f, 0x1b, 0xbf, 0xbe, 0x3d, 0x6e, 0xfc, 0xf1, 0xf6, 0xb8, 0xf1, 0xe2, 0xe3, 0x7f, 0xf7, 0x41, + 0x4c, 0x0b, 0x8e, 0xc2, 0x86, 0x4f, 0xe6, 0x5f, 0x01, 0x00, 0x00, 0xff, 0xff, 0xc5, 0xd7, 0x70, + 0xae, 0x80, 0x0a, 0x00, 0x00, +} + +func (m *EventSource) 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 *EventSource) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *EventSource) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if m.Config != nil { + i -= len(m.Config) + copy(dAtA[i:], m.Config) + i = encodeVarintEvents(dAtA, i, uint64(len(m.Config))) + i-- + dAtA[i] = 0x12 + } + if m.Name == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("name") + } else { + i -= len(*m.Name) + copy(dAtA[i:], *m.Name) + i = encodeVarintEvents(dAtA, i, uint64(len(*m.Name))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *Event) 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 *Event) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Event) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if m.Payload == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("payload") + } else { + i -= len(m.Payload) + copy(dAtA[i:], m.Payload) + i = encodeVarintEvents(dAtA, i, uint64(len(m.Payload))) + i-- + dAtA[i] = 0x12 + } + if m.Name == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("name") + } else { + i -= len(*m.Name) + copy(dAtA[i:], *m.Name) + i = encodeVarintEvents(dAtA, i, uint64(len(*m.Name))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *EventPayload) 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 *EventPayload) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *EventPayload) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + i -= len(m.RuntimeVersion) + copy(dAtA[i:], m.RuntimeVersion) + i = encodeVarintEvents(dAtA, i, uint64(len(m.RuntimeVersion))) + i-- + dAtA[i] = 0x32 + if m.AppVersions != nil { + { + size, err := m.AppVersions.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintEvents(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2a + } + if len(m.Errors) > 0 { + for iNdEx := len(m.Errors) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Errors[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintEvents(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + } + } + if m.Source == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("source") + } else { + { + size, err := m.Source.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintEvents(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + if m.Object == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("object") + } else { + i -= len(m.Object) + copy(dAtA[i:], m.Object) + i = encodeVarintEvents(dAtA, i, uint64(len(m.Object))) + i-- + dAtA[i] = 0x12 + } + i -= len(m.Timestamp) + copy(dAtA[i:], m.Timestamp) + i = encodeVarintEvents(dAtA, i, uint64(len(m.Timestamp))) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *ObjectSource) 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 *ObjectSource) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ObjectSource) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + i = encodeVarintEvents(dAtA, i, uint64(m.AppSourceIdx)) + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0xe0 + i-- + if m.AppMultiSourced { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0xd8 + if m.ClusterName != nil { + i -= len(*m.ClusterName) + copy(dAtA[i:], *m.ClusterName) + i = encodeVarintEvents(dAtA, i, uint64(len(*m.ClusterName))) + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0xd2 + } + if len(m.OperationSyncRevisions) > 0 { + for iNdEx := len(m.OperationSyncRevisions) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.OperationSyncRevisions[iNdEx]) + copy(dAtA[i:], m.OperationSyncRevisions[iNdEx]) + i = encodeVarintEvents(dAtA, i, uint64(len(m.OperationSyncRevisions[iNdEx]))) + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0xca + } + } + 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 = encodeVarintEvents(dAtA, i, uint64(len(m.Revisions[iNdEx]))) + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0xc2 + } + } + i -= len(m.TrackingMethod) + copy(dAtA[i:], m.TrackingMethod) + i = encodeVarintEvents(dAtA, i, uint64(len(m.TrackingMethod))) + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0xba + i -= len(m.AppInstanceLabelKey) + copy(dAtA[i:], m.AppInstanceLabelKey) + i = encodeVarintEvents(dAtA, i, uint64(len(m.AppInstanceLabelKey))) + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0xb2 + i -= len(m.AppNamespace) + copy(dAtA[i:], m.AppNamespace) + i = encodeVarintEvents(dAtA, i, uint64(len(m.AppNamespace))) + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0xaa + i -= len(m.AppUID) + copy(dAtA[i:], m.AppUID) + i = encodeVarintEvents(dAtA, i, uint64(len(m.AppUID))) + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0xa2 + i -= len(m.OperationSyncRevision) + copy(dAtA[i:], m.OperationSyncRevision) + i = encodeVarintEvents(dAtA, i, uint64(len(m.OperationSyncRevision))) + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0x9a + i = encodeVarintEvents(dAtA, i, uint64(m.HistoryId)) + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0x90 + i -= len(m.Cluster) + copy(dAtA[i:], m.Cluster) + i = encodeVarintEvents(dAtA, i, uint64(len(m.Cluster))) + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0x8a + if m.HealthMessage != nil { + i -= len(*m.HealthMessage) + copy(dAtA[i:], *m.HealthMessage) + i = encodeVarintEvents(dAtA, i, uint64(len(*m.HealthMessage))) + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0x82 + } + if m.HealthStatus != nil { + i -= len(*m.HealthStatus) + copy(dAtA[i:], *m.HealthStatus) + i = encodeVarintEvents(dAtA, i, uint64(len(*m.HealthStatus))) + i-- + dAtA[i] = 0x7a + } + if m.SyncFinishedAt != nil { + { + size, err := m.SyncFinishedAt.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintEvents(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x72 + } + { + size, err := m.SyncStartedAt.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintEvents(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x6a + i -= len(m.SyncStatus) + copy(dAtA[i:], m.SyncStatus) + i = encodeVarintEvents(dAtA, i, uint64(len(m.SyncStatus))) + i-- + dAtA[i] = 0x62 + if len(m.AppLabels) > 0 { + for k := range m.AppLabels { + v := m.AppLabels[k] + baseI := i + i -= len(v) + copy(dAtA[i:], v) + i = encodeVarintEvents(dAtA, i, uint64(len(v))) + i-- + dAtA[i] = 0x12 + i -= len(k) + copy(dAtA[i:], k) + i = encodeVarintEvents(dAtA, i, uint64(len(k))) + i-- + dAtA[i] = 0xa + i = encodeVarintEvents(dAtA, i, uint64(baseI-i)) + i-- + dAtA[i] = 0x5a + } + } + i -= len(m.AppName) + copy(dAtA[i:], m.AppName) + i = encodeVarintEvents(dAtA, i, uint64(len(m.AppName))) + i-- + dAtA[i] = 0x52 + if m.CommitDate != nil { + { + size, err := m.CommitDate.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintEvents(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x4a + } + i -= len(m.CommitAuthor) + copy(dAtA[i:], m.CommitAuthor) + i = encodeVarintEvents(dAtA, i, uint64(len(m.CommitAuthor))) + i-- + dAtA[i] = 0x42 + i -= len(m.CommitMessage) + copy(dAtA[i:], m.CommitMessage) + i = encodeVarintEvents(dAtA, i, uint64(len(m.CommitMessage))) + i-- + dAtA[i] = 0x3a + i -= len(m.Revision) + copy(dAtA[i:], m.Revision) + i = encodeVarintEvents(dAtA, i, uint64(len(m.Revision))) + i-- + dAtA[i] = 0x32 + i -= len(m.Path) + copy(dAtA[i:], m.Path) + i = encodeVarintEvents(dAtA, i, uint64(len(m.Path))) + i-- + dAtA[i] = 0x2a + i -= len(m.RepoURL) + copy(dAtA[i:], m.RepoURL) + i = encodeVarintEvents(dAtA, i, uint64(len(m.RepoURL))) + i-- + dAtA[i] = 0x22 + i -= len(m.GitManifest) + copy(dAtA[i:], m.GitManifest) + i = encodeVarintEvents(dAtA, i, uint64(len(m.GitManifest))) + i-- + dAtA[i] = 0x1a + i -= len(m.ActualManifest) + copy(dAtA[i:], m.ActualManifest) + i = encodeVarintEvents(dAtA, i, uint64(len(m.ActualManifest))) + i-- + dAtA[i] = 0x12 + i -= len(m.DesiredManifest) + copy(dAtA[i:], m.DesiredManifest) + i = encodeVarintEvents(dAtA, i, uint64(len(m.DesiredManifest))) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *ObjectError) 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 *ObjectError) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ObjectError) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if m.SourceReference != nil { + { + size, err := m.SourceReference.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintEvents(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2a + } + { + size, err := m.LastSeen.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintEvents(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + i -= len(m.Message) + copy(dAtA[i:], m.Message) + i = encodeVarintEvents(dAtA, i, uint64(len(m.Message))) + i-- + dAtA[i] = 0x1a + i -= len(m.Level) + copy(dAtA[i:], m.Level) + i = encodeVarintEvents(dAtA, i, uint64(len(m.Level))) + i-- + dAtA[i] = 0x12 + i -= len(m.Type) + copy(dAtA[i:], m.Type) + i = encodeVarintEvents(dAtA, i, uint64(len(m.Type))) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *ErrorSourceReference) 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 *ErrorSourceReference) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ErrorSourceReference) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + i -= len(m.Namespace) + copy(dAtA[i:], m.Namespace) + i = encodeVarintEvents(dAtA, i, uint64(len(m.Namespace))) + i-- + dAtA[i] = 0x2a + i -= len(m.Name) + copy(dAtA[i:], m.Name) + i = encodeVarintEvents(dAtA, i, uint64(len(m.Name))) + i-- + dAtA[i] = 0x22 + i -= len(m.Kind) + copy(dAtA[i:], m.Kind) + i = encodeVarintEvents(dAtA, i, uint64(len(m.Kind))) + i-- + dAtA[i] = 0x1a + i -= len(m.Version) + copy(dAtA[i:], m.Version) + i = encodeVarintEvents(dAtA, i, uint64(len(m.Version))) + i-- + dAtA[i] = 0x12 + i -= len(m.Group) + copy(dAtA[i:], m.Group) + i = encodeVarintEvents(dAtA, i, uint64(len(m.Group))) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *Dependencies) 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 *Dependencies) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Dependencies) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if m.Requirements != nil { + i -= len(*m.Requirements) + copy(dAtA[i:], *m.Requirements) + i = encodeVarintEvents(dAtA, i, uint64(len(*m.Requirements))) + i-- + dAtA[i] = 0x1a + } + if m.Deps != nil { + i -= len(*m.Deps) + copy(dAtA[i:], *m.Deps) + i = encodeVarintEvents(dAtA, i, uint64(len(*m.Deps))) + i-- + dAtA[i] = 0x12 + } + if m.Lock != nil { + i -= len(*m.Lock) + copy(dAtA[i:], *m.Lock) + i = encodeVarintEvents(dAtA, i, uint64(len(*m.Lock))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *ApplicationVersions) 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 *ApplicationVersions) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ApplicationVersions) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if m.Dependencies != nil { + { + size, err := m.Dependencies.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintEvents(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + if m.AppVersion != nil { + i -= len(*m.AppVersion) + copy(dAtA[i:], *m.AppVersion) + i = encodeVarintEvents(dAtA, i, uint64(len(*m.AppVersion))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func encodeVarintEvents(dAtA []byte, offset int, v uint64) int { + offset -= sovEvents(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *EventSource) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Name != nil { + l = len(*m.Name) + n += 1 + l + sovEvents(uint64(l)) + } + if m.Config != nil { + l = len(m.Config) + n += 1 + l + sovEvents(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *Event) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Name != nil { + l = len(*m.Name) + n += 1 + l + sovEvents(uint64(l)) + } + if m.Payload != nil { + l = len(m.Payload) + n += 1 + l + sovEvents(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *EventPayload) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Timestamp) + n += 1 + l + sovEvents(uint64(l)) + if m.Object != nil { + l = len(m.Object) + n += 1 + l + sovEvents(uint64(l)) + } + if m.Source != nil { + l = m.Source.Size() + n += 1 + l + sovEvents(uint64(l)) + } + if len(m.Errors) > 0 { + for _, e := range m.Errors { + l = e.Size() + n += 1 + l + sovEvents(uint64(l)) + } + } + if m.AppVersions != nil { + l = m.AppVersions.Size() + n += 1 + l + sovEvents(uint64(l)) + } + l = len(m.RuntimeVersion) + n += 1 + l + sovEvents(uint64(l)) + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *ObjectSource) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.DesiredManifest) + n += 1 + l + sovEvents(uint64(l)) + l = len(m.ActualManifest) + n += 1 + l + sovEvents(uint64(l)) + l = len(m.GitManifest) + n += 1 + l + sovEvents(uint64(l)) + l = len(m.RepoURL) + n += 1 + l + sovEvents(uint64(l)) + l = len(m.Path) + n += 1 + l + sovEvents(uint64(l)) + l = len(m.Revision) + n += 1 + l + sovEvents(uint64(l)) + l = len(m.CommitMessage) + n += 1 + l + sovEvents(uint64(l)) + l = len(m.CommitAuthor) + n += 1 + l + sovEvents(uint64(l)) + if m.CommitDate != nil { + l = m.CommitDate.Size() + n += 1 + l + sovEvents(uint64(l)) + } + l = len(m.AppName) + n += 1 + l + sovEvents(uint64(l)) + if len(m.AppLabels) > 0 { + for k, v := range m.AppLabels { + _ = k + _ = v + mapEntrySize := 1 + len(k) + sovEvents(uint64(len(k))) + 1 + len(v) + sovEvents(uint64(len(v))) + n += mapEntrySize + 1 + sovEvents(uint64(mapEntrySize)) + } + } + l = len(m.SyncStatus) + n += 1 + l + sovEvents(uint64(l)) + l = m.SyncStartedAt.Size() + n += 1 + l + sovEvents(uint64(l)) + if m.SyncFinishedAt != nil { + l = m.SyncFinishedAt.Size() + n += 1 + l + sovEvents(uint64(l)) + } + if m.HealthStatus != nil { + l = len(*m.HealthStatus) + n += 1 + l + sovEvents(uint64(l)) + } + if m.HealthMessage != nil { + l = len(*m.HealthMessage) + n += 2 + l + sovEvents(uint64(l)) + } + l = len(m.Cluster) + n += 2 + l + sovEvents(uint64(l)) + n += 2 + sovEvents(uint64(m.HistoryId)) + l = len(m.OperationSyncRevision) + n += 2 + l + sovEvents(uint64(l)) + l = len(m.AppUID) + n += 2 + l + sovEvents(uint64(l)) + l = len(m.AppNamespace) + n += 2 + l + sovEvents(uint64(l)) + l = len(m.AppInstanceLabelKey) + n += 2 + l + sovEvents(uint64(l)) + l = len(m.TrackingMethod) + n += 2 + l + sovEvents(uint64(l)) + if len(m.Revisions) > 0 { + for _, s := range m.Revisions { + l = len(s) + n += 2 + l + sovEvents(uint64(l)) + } + } + if len(m.OperationSyncRevisions) > 0 { + for _, s := range m.OperationSyncRevisions { + l = len(s) + n += 2 + l + sovEvents(uint64(l)) + } + } + if m.ClusterName != nil { + l = len(*m.ClusterName) + n += 2 + l + sovEvents(uint64(l)) + } + n += 3 + n += 2 + sovEvents(uint64(m.AppSourceIdx)) + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *ObjectError) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Type) + n += 1 + l + sovEvents(uint64(l)) + l = len(m.Level) + n += 1 + l + sovEvents(uint64(l)) + l = len(m.Message) + n += 1 + l + sovEvents(uint64(l)) + l = m.LastSeen.Size() + n += 1 + l + sovEvents(uint64(l)) + if m.SourceReference != nil { + l = m.SourceReference.Size() + n += 1 + l + sovEvents(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *ErrorSourceReference) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Group) + n += 1 + l + sovEvents(uint64(l)) + l = len(m.Version) + n += 1 + l + sovEvents(uint64(l)) + l = len(m.Kind) + n += 1 + l + sovEvents(uint64(l)) + l = len(m.Name) + n += 1 + l + sovEvents(uint64(l)) + l = len(m.Namespace) + n += 1 + l + sovEvents(uint64(l)) + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *Dependencies) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Lock != nil { + l = len(*m.Lock) + n += 1 + l + sovEvents(uint64(l)) + } + if m.Deps != nil { + l = len(*m.Deps) + n += 1 + l + sovEvents(uint64(l)) + } + if m.Requirements != nil { + l = len(*m.Requirements) + n += 1 + l + sovEvents(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *ApplicationVersions) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.AppVersion != nil { + l = len(*m.AppVersion) + n += 1 + l + sovEvents(uint64(l)) + } + if m.Dependencies != nil { + l = m.Dependencies.Size() + n += 1 + l + sovEvents(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func sovEvents(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozEvents(x uint64) (n int) { + return sovEvents(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *EventSource) Unmarshal(dAtA []byte) error { + var hasFields [1]uint64 + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + 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: EventSource: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: EventSource: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + 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 ErrInvalidLengthEvents + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(dAtA[iNdEx:postIndex]) + m.Name = &s + iNdEx = postIndex + hasFields[0] |= uint64(0x00000001) + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Config", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Config = append(m.Config[:0], dAtA[iNdEx:postIndex]...) + if m.Config == nil { + m.Config = []byte{} + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipEvents(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthEvents + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + if hasFields[0]&uint64(0x00000001) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("name") + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Event) Unmarshal(dAtA []byte) error { + var hasFields [1]uint64 + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + 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: Event: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Event: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + 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 ErrInvalidLengthEvents + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(dAtA[iNdEx:postIndex]) + m.Name = &s + iNdEx = postIndex + hasFields[0] |= uint64(0x00000001) + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Payload", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Payload = append(m.Payload[:0], dAtA[iNdEx:postIndex]...) + if m.Payload == nil { + m.Payload = []byte{} + } + iNdEx = postIndex + hasFields[0] |= uint64(0x00000002) + default: + iNdEx = preIndex + skippy, err := skipEvents(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthEvents + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + if hasFields[0]&uint64(0x00000001) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("name") + } + if hasFields[0]&uint64(0x00000002) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("payload") + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *EventPayload) Unmarshal(dAtA []byte) error { + var hasFields [1]uint64 + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + 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: EventPayload: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: EventPayload: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Timestamp", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + 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 ErrInvalidLengthEvents + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Timestamp = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + hasFields[0] |= uint64(0x00000001) + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Object", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Object = append(m.Object[:0], dAtA[iNdEx:postIndex]...) + if m.Object == nil { + m.Object = []byte{} + } + iNdEx = postIndex + hasFields[0] |= uint64(0x00000002) + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Source", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Source == nil { + m.Source = &ObjectSource{} + } + if err := m.Source.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + hasFields[0] |= uint64(0x00000004) + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Errors", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Errors = append(m.Errors, &ObjectError{}) + if err := m.Errors[len(m.Errors)-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 AppVersions", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.AppVersions == nil { + m.AppVersions = &ApplicationVersions{} + } + if err := m.AppVersions.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field RuntimeVersion", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + 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 ErrInvalidLengthEvents + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.RuntimeVersion = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + hasFields[0] |= uint64(0x00000008) + default: + iNdEx = preIndex + skippy, err := skipEvents(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthEvents + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + if hasFields[0]&uint64(0x00000001) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("timestamp") + } + if hasFields[0]&uint64(0x00000002) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("object") + } + if hasFields[0]&uint64(0x00000004) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("source") + } + if hasFields[0]&uint64(0x00000008) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("runtimeVersion") + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ObjectSource) Unmarshal(dAtA []byte) error { + var hasFields [1]uint64 + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + 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: ObjectSource: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ObjectSource: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field DesiredManifest", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + 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 ErrInvalidLengthEvents + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.DesiredManifest = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ActualManifest", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + 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 ErrInvalidLengthEvents + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ActualManifest = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field GitManifest", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + 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 ErrInvalidLengthEvents + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.GitManifest = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field RepoURL", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + 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 ErrInvalidLengthEvents + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.RepoURL = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Path", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + 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 ErrInvalidLengthEvents + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Path = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Revision", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + 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 ErrInvalidLengthEvents + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Revision = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field CommitMessage", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + 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 ErrInvalidLengthEvents + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.CommitMessage = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field CommitAuthor", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + 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 ErrInvalidLengthEvents + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.CommitAuthor = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 9: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field CommitDate", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.CommitDate == nil { + m.CommitDate = &v1.Time{} + } + if err := m.CommitDate.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 10: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AppName", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + 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 ErrInvalidLengthEvents + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AppName = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 11: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AppLabels", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.AppLabels == nil { + m.AppLabels = make(map[string]string) + } + var mapkey string + var mapvalue string + for iNdEx < postIndex { + entryPreIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + 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 ErrIntOverflowEvents + } + 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 ErrInvalidLengthEvents + } + postStringIndexmapkey := iNdEx + intStringLenmapkey + if postStringIndexmapkey < 0 { + return ErrInvalidLengthEvents + } + if postStringIndexmapkey > l { + return io.ErrUnexpectedEOF + } + mapkey = string(dAtA[iNdEx:postStringIndexmapkey]) + iNdEx = postStringIndexmapkey + } else if fieldNum == 2 { + var stringLenmapvalue uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLenmapvalue |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLenmapvalue := int(stringLenmapvalue) + if intStringLenmapvalue < 0 { + return ErrInvalidLengthEvents + } + postStringIndexmapvalue := iNdEx + intStringLenmapvalue + if postStringIndexmapvalue < 0 { + return ErrInvalidLengthEvents + } + if postStringIndexmapvalue > l { + return io.ErrUnexpectedEOF + } + mapvalue = string(dAtA[iNdEx:postStringIndexmapvalue]) + iNdEx = postStringIndexmapvalue + } else { + iNdEx = entryPreIndex + skippy, err := skipEvents(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthEvents + } + if (iNdEx + skippy) > postIndex { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + m.AppLabels[mapkey] = mapvalue + iNdEx = postIndex + case 12: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SyncStatus", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + 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 ErrInvalidLengthEvents + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.SyncStatus = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 13: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SyncStartedAt", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.SyncStartedAt.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 14: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SyncFinishedAt", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.SyncFinishedAt == nil { + m.SyncFinishedAt = &v1.Time{} + } + if err := m.SyncFinishedAt.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 15: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field HealthStatus", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + 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 ErrInvalidLengthEvents + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(dAtA[iNdEx:postIndex]) + m.HealthStatus = &s + iNdEx = postIndex + case 16: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field HealthMessage", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + 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 ErrInvalidLengthEvents + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(dAtA[iNdEx:postIndex]) + m.HealthMessage = &s + iNdEx = postIndex + case 17: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Cluster", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + 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 ErrInvalidLengthEvents + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Cluster = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 18: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field HistoryId", wireType) + } + m.HistoryId = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.HistoryId |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 19: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field OperationSyncRevision", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + 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 ErrInvalidLengthEvents + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.OperationSyncRevision = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 20: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AppUID", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + 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 ErrInvalidLengthEvents + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AppUID = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 21: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AppNamespace", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + 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 ErrInvalidLengthEvents + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AppNamespace = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 22: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AppInstanceLabelKey", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + 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 ErrInvalidLengthEvents + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AppInstanceLabelKey = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 23: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TrackingMethod", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + 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 ErrInvalidLengthEvents + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.TrackingMethod = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 24: + 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 ErrIntOverflowEvents + } + 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 ErrInvalidLengthEvents + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Revisions = append(m.Revisions, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + case 25: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field OperationSyncRevisions", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + 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 ErrInvalidLengthEvents + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.OperationSyncRevisions = append(m.OperationSyncRevisions, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + case 26: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ClusterName", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + 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 ErrInvalidLengthEvents + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(dAtA[iNdEx:postIndex]) + m.ClusterName = &s + iNdEx = postIndex + case 27: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field AppMultiSourced", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.AppMultiSourced = bool(v != 0) + hasFields[0] |= uint64(0x00000001) + case 28: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field AppSourceIdx", wireType) + } + m.AppSourceIdx = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.AppSourceIdx |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + hasFields[0] |= uint64(0x00000002) + default: + iNdEx = preIndex + skippy, err := skipEvents(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthEvents + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + if hasFields[0]&uint64(0x00000001) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("appMultiSourced") + } + if hasFields[0]&uint64(0x00000002) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("appSourceIdx") + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ObjectError) 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 ErrIntOverflowEvents + } + 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: ObjectError: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ObjectError: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + 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 ErrInvalidLengthEvents + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Type = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Level", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + 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 ErrInvalidLengthEvents + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Level = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Message", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + 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 ErrInvalidLengthEvents + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Message = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field LastSeen", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.LastSeen.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SourceReference", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.SourceReference == nil { + m.SourceReference = &ErrorSourceReference{} + } + if err := m.SourceReference.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipEvents(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthEvents + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ErrorSourceReference) Unmarshal(dAtA []byte) error { + var hasFields [1]uint64 + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + 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: ErrorSourceReference: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ErrorSourceReference: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Group", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + 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 ErrInvalidLengthEvents + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Group = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Version", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + 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 ErrInvalidLengthEvents + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Version = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Kind", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + 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 ErrInvalidLengthEvents + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Kind = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + hasFields[0] |= uint64(0x00000001) + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + 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 ErrInvalidLengthEvents + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + hasFields[0] |= uint64(0x00000002) + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Namespace", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + 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 ErrInvalidLengthEvents + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Namespace = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipEvents(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthEvents + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + if hasFields[0]&uint64(0x00000001) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("kind") + } + if hasFields[0]&uint64(0x00000002) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("name") + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Dependencies) 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 ErrIntOverflowEvents + } + 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: Dependencies: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Dependencies: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Lock", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + 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 ErrInvalidLengthEvents + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(dAtA[iNdEx:postIndex]) + m.Lock = &s + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Deps", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + 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 ErrInvalidLengthEvents + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(dAtA[iNdEx:postIndex]) + m.Deps = &s + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Requirements", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + 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 ErrInvalidLengthEvents + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(dAtA[iNdEx:postIndex]) + m.Requirements = &s + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipEvents(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthEvents + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ApplicationVersions) 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 ErrIntOverflowEvents + } + 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: ApplicationVersions: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ApplicationVersions: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AppVersion", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + 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 ErrInvalidLengthEvents + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(dAtA[iNdEx:postIndex]) + m.AppVersion = &s + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Dependencies", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Dependencies == nil { + m.Dependencies = &Dependencies{} + } + if err := m.Dependencies.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipEvents(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthEvents + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipEvents(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowEvents + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowEvents + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowEvents + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthEvents + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupEvents + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthEvents + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthEvents = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowEvents = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupEvents = fmt.Errorf("proto: unexpected end of group") +) diff --git a/pkg/apis/application/v1alpha1/cf_types.go b/pkg/apis/application/v1alpha1/cf_types.go new file mode 100644 index 0000000000000..1e2d922b407a4 --- /dev/null +++ b/pkg/apis/application/v1alpha1/cf_types.go @@ -0,0 +1,41 @@ +package v1alpha1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + appv1reg "github.com/argoproj/argo-cd/v2/pkg/apis/application" +) + +func (a *Application) IsEmptyTypeMeta() bool { + return a.TypeMeta.Size() == 0 || a.TypeMeta.Kind == "" || a.TypeMeta.APIVersion == "" +} + +func (a *Application) SetDefaultTypeMeta() { + a.TypeMeta = metav1.TypeMeta{ + Kind: appv1reg.ApplicationKind, + APIVersion: SchemeGroupVersion.String(), + } +} + +func (spec *ApplicationSpec) GetNonRefSource() (*ApplicationSource, int) { + if spec.HasMultipleSources() { + for idx, source := range spec.Sources { + if !source.IsRef() { + return &source, idx + } + } + } + + if spec.Source == nil { + return nil, -2 + } + + // single source app + return spec.Source, -1 +} + +func (spec *ApplicationSpec) SourceUnderIdxIsHelm(idx int) bool { + source := spec.GetSourcePtrByIndex(idx) + + return source != nil && source.IsHelm() +} diff --git a/pkg/apis/application/v1alpha1/generated.pb.go b/pkg/apis/application/v1alpha1/generated.pb.go index bdb2368203f3b..05c56aef6142f 100644 --- a/pkg/apis/application/v1alpha1/generated.pb.go +++ b/pkg/apis/application/v1alpha1/generated.pb.go @@ -4754,6 +4754,8 @@ func init() { proto.RegisterMapType((map[string]string)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ResourceNetworkingInfo.LabelsEntry") proto.RegisterMapType((map[string]string)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ResourceNetworkingInfo.TargetLabelsEntry") proto.RegisterType((*ResourceNode)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ResourceNode") + proto.RegisterMapType((map[string]string)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ResourceNode.AnnotationsEntry") + proto.RegisterMapType((map[string]string)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ResourceNode.LabelsEntry") proto.RegisterType((*ResourceOverride)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ResourceOverride") proto.RegisterType((*ResourceRef)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ResourceRef") proto.RegisterType((*ResourceResult)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ResourceResult") @@ -4796,749 +4798,752 @@ func init() { } var fileDescriptor_030104ce3b95bcac = []byte{ - // 11861 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0xbd, 0x7d, 0x70, 0x1c, 0xc9, - 0x75, 0x18, 0xae, 0xd9, 0xc5, 0x02, 0xbb, 0x0f, 0x5f, 0x64, 0x93, 0xbc, 0xc3, 0xf1, 0x3e, 0x40, - 0xcf, 0xc9, 0xa7, 0xf3, 0x4f, 0x77, 0x80, 0x8f, 0xbe, 0x93, 0xef, 0xe7, 0xb3, 0x24, 0xe3, 0x83, - 0x04, 0x41, 0x02, 0x04, 0xae, 0x17, 0x24, 0xa5, 0x93, 0x4f, 0xa7, 0xc1, 0x6e, 0x63, 0x31, 0xc4, - 0xec, 0xcc, 0xde, 0xcc, 0x2c, 0x88, 0x3d, 0x4b, 0xb2, 0x64, 0x49, 0xb6, 0x6c, 0x7d, 0x46, 0x4a, - 0xc5, 0xe7, 0xc4, 0x52, 0x64, 0x4b, 0x49, 0x25, 0x95, 0x52, 0x59, 0x89, 0xff, 0x88, 0x53, 0xb6, - 0xcb, 0x15, 0x3b, 0xe5, 0x52, 0xe2, 0xa4, 0xec, 0xa8, 0x54, 0x96, 0x12, 0xdb, 0x88, 0xc4, 0x38, - 0x65, 0x57, 0xfe, 0x70, 0x55, 0x9c, 0xfc, 0x91, 0x62, 0x5c, 0xa9, 0x54, 0x7f, 0xf7, 0xcc, 0xce, - 0x02, 0x0b, 0x62, 0x00, 0x52, 0xf2, 0xfd, 0xb7, 0xdb, 0xef, 0xcd, 0x7b, 0x3d, 0x3d, 0xdd, 0xef, - 0xbd, 0x7e, 0xfd, 0xde, 0x6b, 0x58, 0x6a, 0xb8, 0xf1, 0x66, 0x7b, 0x7d, 0xaa, 0x16, 0x34, 0xa7, - 0x9d, 0xb0, 0x11, 0xb4, 0xc2, 0xe0, 0x26, 0xfb, 0xf1, 0x74, 0xad, 0x3e, 0xbd, 0x7d, 0x7e, 0xba, - 0xb5, 0xd5, 0x98, 0x76, 0x5a, 0x6e, 0x34, 0xed, 0xb4, 0x5a, 0x9e, 0x5b, 0x73, 0x62, 0x37, 0xf0, - 0xa7, 0xb7, 0x9f, 0x71, 0xbc, 0xd6, 0xa6, 0xf3, 0xcc, 0x74, 0x83, 0xf8, 0x24, 0x74, 0x62, 0x52, - 0x9f, 0x6a, 0x85, 0x41, 0x1c, 0xa0, 0x1f, 0xd7, 0xd4, 0xa6, 0x24, 0x35, 0xf6, 0xe3, 0x95, 0x5a, - 0x7d, 0x6a, 0xfb, 0xfc, 0x54, 0x6b, 0xab, 0x31, 0x45, 0xa9, 0x4d, 0x19, 0xd4, 0xa6, 0x24, 0xb5, - 0xb3, 0x4f, 0x1b, 0x7d, 0x69, 0x04, 0x8d, 0x60, 0x9a, 0x11, 0x5d, 0x6f, 0x6f, 0xb0, 0x7f, 0xec, - 0x0f, 0xfb, 0xc5, 0x99, 0x9d, 0xb5, 0xb7, 0x9e, 0x8f, 0xa6, 0xdc, 0x80, 0x76, 0x6f, 0xba, 0x16, - 0x84, 0x64, 0x7a, 0xbb, 0xab, 0x43, 0x67, 0x2f, 0x69, 0x1c, 0xb2, 0x13, 0x13, 0x3f, 0x72, 0x03, - 0x3f, 0x7a, 0x9a, 0x76, 0x81, 0x84, 0xdb, 0x24, 0x34, 0x5f, 0xcf, 0x40, 0xc8, 0xa2, 0xf4, 0xac, - 0xa6, 0xd4, 0x74, 0x6a, 0x9b, 0xae, 0x4f, 0xc2, 0x8e, 0x7e, 0xbc, 0x49, 0x62, 0x27, 0xeb, 0xa9, - 0xe9, 0x5e, 0x4f, 0x85, 0x6d, 0x3f, 0x76, 0x9b, 0xa4, 0xeb, 0x81, 0xb7, 0xed, 0xf7, 0x40, 0x54, - 0xdb, 0x24, 0x4d, 0xa7, 0xeb, 0xb9, 0x1f, 0xe9, 0xf5, 0x5c, 0x3b, 0x76, 0xbd, 0x69, 0xd7, 0x8f, - 0xa3, 0x38, 0x4c, 0x3f, 0x64, 0xff, 0xb2, 0x05, 0xa3, 0x33, 0x37, 0xaa, 0x33, 0xed, 0x78, 0x73, - 0x2e, 0xf0, 0x37, 0xdc, 0x06, 0x7a, 0x0e, 0x86, 0x6b, 0x5e, 0x3b, 0x8a, 0x49, 0x78, 0xd5, 0x69, - 0x92, 0x09, 0xeb, 0x9c, 0xf5, 0x64, 0x65, 0xf6, 0xd4, 0xd7, 0x77, 0x27, 0xdf, 0x74, 0x7b, 0x77, - 0x72, 0x78, 0x4e, 0x83, 0xb0, 0x89, 0x87, 0x7e, 0x08, 0x86, 0xc2, 0xc0, 0x23, 0x33, 0xf8, 0xea, - 0x44, 0x81, 0x3d, 0x32, 0x2e, 0x1e, 0x19, 0xc2, 0xbc, 0x19, 0x4b, 0x38, 0x45, 0x6d, 0x85, 0xc1, - 0x86, 0xeb, 0x91, 0x89, 0x62, 0x12, 0x75, 0x95, 0x37, 0x63, 0x09, 0xb7, 0xff, 0xb8, 0x00, 0x30, - 0xd3, 0x6a, 0xad, 0x86, 0xc1, 0x4d, 0x52, 0x8b, 0xd1, 0xfb, 0xa0, 0x4c, 0x87, 0xb9, 0xee, 0xc4, - 0x0e, 0xeb, 0xd8, 0xf0, 0xf9, 0x1f, 0x9e, 0xe2, 0x6f, 0x3d, 0x65, 0xbe, 0xb5, 0x9e, 0x64, 0x14, - 0x7b, 0x6a, 0xfb, 0x99, 0xa9, 0x95, 0x75, 0xfa, 0xfc, 0x32, 0x89, 0x9d, 0x59, 0x24, 0x98, 0x81, - 0x6e, 0xc3, 0x8a, 0x2a, 0xf2, 0x61, 0x20, 0x6a, 0x91, 0x1a, 0x7b, 0x87, 0xe1, 0xf3, 0x4b, 0x53, - 0x87, 0x99, 0xcd, 0x53, 0xba, 0xe7, 0xd5, 0x16, 0xa9, 0xcd, 0x8e, 0x08, 0xce, 0x03, 0xf4, 0x1f, - 0x66, 0x7c, 0xd0, 0x36, 0x0c, 0x46, 0xb1, 0x13, 0xb7, 0x23, 0x36, 0x14, 0xc3, 0xe7, 0xaf, 0xe6, - 0xc6, 0x91, 0x51, 0x9d, 0x1d, 0x13, 0x3c, 0x07, 0xf9, 0x7f, 0x2c, 0xb8, 0xd9, 0x7f, 0x66, 0xc1, - 0x98, 0x46, 0x5e, 0x72, 0xa3, 0x18, 0xfd, 0x64, 0xd7, 0xe0, 0x4e, 0xf5, 0x37, 0xb8, 0xf4, 0x69, - 0x36, 0xb4, 0x27, 0x04, 0xb3, 0xb2, 0x6c, 0x31, 0x06, 0xb6, 0x09, 0x25, 0x37, 0x26, 0xcd, 0x68, - 0xa2, 0x70, 0xae, 0xf8, 0xe4, 0xf0, 0xf9, 0x4b, 0x79, 0xbd, 0xe7, 0xec, 0xa8, 0x60, 0x5a, 0x5a, - 0xa4, 0xe4, 0x31, 0xe7, 0x62, 0xff, 0xf5, 0xa8, 0xf9, 0x7e, 0x74, 0xc0, 0xd1, 0x33, 0x30, 0x1c, - 0x05, 0xed, 0xb0, 0x46, 0x30, 0x69, 0x05, 0xd1, 0x84, 0x75, 0xae, 0x48, 0xa7, 0x1e, 0x9d, 0xd4, - 0x55, 0xdd, 0x8c, 0x4d, 0x1c, 0xf4, 0x69, 0x0b, 0x46, 0xea, 0x24, 0x8a, 0x5d, 0x9f, 0xf1, 0x97, - 0x9d, 0x5f, 0x3b, 0x74, 0xe7, 0x65, 0xe3, 0xbc, 0x26, 0x3e, 0x7b, 0x5a, 0xbc, 0xc8, 0x88, 0xd1, - 0x18, 0xe1, 0x04, 0x7f, 0xba, 0x38, 0xeb, 0x24, 0xaa, 0x85, 0x6e, 0x8b, 0xfe, 0x17, 0xcb, 0x47, - 0x2d, 0xce, 0x79, 0x0d, 0xc2, 0x26, 0x1e, 0xf2, 0xa1, 0x44, 0x17, 0x5f, 0x34, 0x31, 0xc0, 0xfa, - 0xbf, 0x78, 0xb8, 0xfe, 0x8b, 0x41, 0xa5, 0xeb, 0x5a, 0x8f, 0x3e, 0xfd, 0x17, 0x61, 0xce, 0x06, - 0x7d, 0xca, 0x82, 0x09, 0x21, 0x1c, 0x30, 0xe1, 0x03, 0x7a, 0x63, 0xd3, 0x8d, 0x89, 0xe7, 0x46, - 0xf1, 0x44, 0x89, 0xf5, 0x61, 0xba, 0xbf, 0xb9, 0xb5, 0x10, 0x06, 0xed, 0xd6, 0x15, 0xd7, 0xaf, - 0xcf, 0x9e, 0x13, 0x9c, 0x26, 0xe6, 0x7a, 0x10, 0xc6, 0x3d, 0x59, 0xa2, 0xcf, 0x5b, 0x70, 0xd6, - 0x77, 0x9a, 0x24, 0x6a, 0x39, 0xf4, 0xd3, 0x72, 0xf0, 0xac, 0xe7, 0xd4, 0xb6, 0x58, 0x8f, 0x06, - 0xef, 0xae, 0x47, 0xb6, 0xe8, 0xd1, 0xd9, 0xab, 0x3d, 0x49, 0xe3, 0x3d, 0xd8, 0xa2, 0x2f, 0x5b, - 0x70, 0x32, 0x08, 0x5b, 0x9b, 0x8e, 0x4f, 0xea, 0x12, 0x1a, 0x4d, 0x0c, 0xb1, 0xa5, 0xf7, 0xde, - 0xc3, 0x7d, 0xa2, 0x95, 0x34, 0xd9, 0xe5, 0xc0, 0x77, 0xe3, 0x20, 0xac, 0x92, 0x38, 0x76, 0xfd, - 0x46, 0x34, 0x7b, 0xe6, 0xf6, 0xee, 0xe4, 0xc9, 0x2e, 0x2c, 0xdc, 0xdd, 0x1f, 0xf4, 0x53, 0x30, - 0x1c, 0x75, 0xfc, 0xda, 0x0d, 0xd7, 0xaf, 0x07, 0xb7, 0xa2, 0x89, 0x72, 0x1e, 0xcb, 0xb7, 0xaa, - 0x08, 0x8a, 0x05, 0xa8, 0x19, 0x60, 0x93, 0x5b, 0xf6, 0x87, 0xd3, 0x53, 0xa9, 0x92, 0xf7, 0x87, - 0xd3, 0x93, 0x69, 0x0f, 0xb6, 0xe8, 0xe7, 0x2c, 0x18, 0x8d, 0xdc, 0x86, 0xef, 0xc4, 0xed, 0x90, - 0x5c, 0x21, 0x9d, 0x68, 0x02, 0x58, 0x47, 0x2e, 0x1f, 0x72, 0x54, 0x0c, 0x92, 0xb3, 0x67, 0x44, - 0x1f, 0x47, 0xcd, 0xd6, 0x08, 0x27, 0xf9, 0x66, 0x2d, 0x34, 0x3d, 0xad, 0x87, 0xf3, 0x5d, 0x68, - 0x7a, 0x52, 0xf7, 0x64, 0x89, 0x7e, 0x02, 0x4e, 0xf0, 0x26, 0x35, 0xb2, 0xd1, 0xc4, 0x08, 0x13, - 0xb4, 0xa7, 0x6f, 0xef, 0x4e, 0x9e, 0xa8, 0xa6, 0x60, 0xb8, 0x0b, 0x1b, 0xbd, 0x0a, 0x93, 0x2d, - 0x12, 0x36, 0xdd, 0x78, 0xc5, 0xf7, 0x3a, 0x52, 0x7c, 0xd7, 0x82, 0x16, 0xa9, 0x8b, 0xee, 0x44, - 0x13, 0xa3, 0xe7, 0xac, 0x27, 0xcb, 0xb3, 0x6f, 0x11, 0xdd, 0x9c, 0x5c, 0xdd, 0x1b, 0x1d, 0xef, - 0x47, 0x0f, 0xfd, 0xbe, 0x05, 0x67, 0x0d, 0x29, 0x5b, 0x25, 0xe1, 0xb6, 0x5b, 0x23, 0x33, 0xb5, - 0x5a, 0xd0, 0xf6, 0xe3, 0x68, 0x62, 0x8c, 0x0d, 0xe3, 0xfa, 0x51, 0xc8, 0xfc, 0x24, 0x2b, 0x3d, - 0x2f, 0x7b, 0xa2, 0x44, 0x78, 0x8f, 0x9e, 0xda, 0xff, 0xb6, 0x00, 0x27, 0xd2, 0x16, 0x00, 0xfa, - 0xc7, 0x16, 0x8c, 0xdf, 0xbc, 0x15, 0xaf, 0x05, 0x5b, 0xc4, 0x8f, 0x66, 0x3b, 0x54, 0x4e, 0x33, - 0xdd, 0x37, 0x7c, 0xbe, 0x96, 0xaf, 0xad, 0x31, 0x75, 0x39, 0xc9, 0xe5, 0x82, 0x1f, 0x87, 0x9d, - 0xd9, 0x07, 0xc5, 0x3b, 0x8d, 0x5f, 0xbe, 0xb1, 0x66, 0x42, 0x71, 0xba, 0x53, 0x67, 0x3f, 0x61, - 0xc1, 0xe9, 0x2c, 0x12, 0xe8, 0x04, 0x14, 0xb7, 0x48, 0x87, 0x5b, 0xa2, 0x98, 0xfe, 0x44, 0x2f, - 0x43, 0x69, 0xdb, 0xf1, 0xda, 0x44, 0x98, 0x69, 0x0b, 0x87, 0x7b, 0x11, 0xd5, 0x33, 0xcc, 0xa9, - 0xfe, 0x58, 0xe1, 0x79, 0xcb, 0xfe, 0xc3, 0x22, 0x0c, 0x1b, 0x1f, 0xed, 0x18, 0x4c, 0xcf, 0x20, - 0x61, 0x7a, 0x2e, 0xe7, 0x36, 0xdf, 0x7a, 0xda, 0x9e, 0xb7, 0x52, 0xb6, 0xe7, 0x4a, 0x7e, 0x2c, - 0xf7, 0x34, 0x3e, 0x51, 0x0c, 0x95, 0xa0, 0x45, 0xb7, 0x21, 0xd4, 0x86, 0x19, 0xc8, 0xe3, 0x13, - 0xae, 0x48, 0x72, 0xb3, 0xa3, 0xb7, 0x77, 0x27, 0x2b, 0xea, 0x2f, 0xd6, 0x8c, 0xec, 0x6f, 0x59, - 0x70, 0xda, 0xe8, 0xe3, 0x5c, 0xe0, 0xd7, 0x5d, 0xf6, 0x69, 0xcf, 0xc1, 0x40, 0xdc, 0x69, 0xc9, - 0xad, 0x8e, 0x1a, 0xa9, 0xb5, 0x4e, 0x8b, 0x60, 0x06, 0xa1, 0x3b, 0x96, 0x26, 0x89, 0x22, 0xa7, - 0x41, 0xd2, 0x9b, 0x9b, 0x65, 0xde, 0x8c, 0x25, 0x1c, 0x85, 0x80, 0x3c, 0x27, 0x8a, 0xd7, 0x42, - 0xc7, 0x8f, 0x18, 0xf9, 0x35, 0xb7, 0x49, 0xc4, 0x00, 0xff, 0x7f, 0xfd, 0xcd, 0x18, 0xfa, 0xc4, - 0xec, 0x03, 0xb7, 0x77, 0x27, 0xd1, 0x52, 0x17, 0x25, 0x9c, 0x41, 0xdd, 0xfe, 0xbc, 0x05, 0x0f, - 0x64, 0x0b, 0x18, 0xf4, 0x04, 0x0c, 0xf2, 0x7d, 0xae, 0x78, 0x3b, 0xfd, 0x49, 0x58, 0x2b, 0x16, - 0x50, 0x34, 0x0d, 0x15, 0xa5, 0xf0, 0xc4, 0x3b, 0x9e, 0x14, 0xa8, 0x15, 0xad, 0x25, 0x35, 0x0e, - 0x1d, 0x34, 0xfa, 0x47, 0x98, 0xa0, 0x6a, 0xd0, 0xd8, 0xc6, 0x90, 0x41, 0xec, 0x6f, 0x5a, 0xf0, - 0xe6, 0x7e, 0xc4, 0xde, 0xd1, 0xf5, 0xb1, 0x0a, 0x67, 0xea, 0x64, 0xc3, 0x69, 0x7b, 0x71, 0x92, - 0xa3, 0xe8, 0xf4, 0xa3, 0xe2, 0xe1, 0x33, 0xf3, 0x59, 0x48, 0x38, 0xfb, 0x59, 0xfb, 0xbf, 0x58, - 0x30, 0x6e, 0xbc, 0xd6, 0x31, 0x6c, 0x9d, 0xfc, 0xe4, 0xd6, 0x69, 0x31, 0xb7, 0x65, 0xda, 0x63, - 0xef, 0xf4, 0x29, 0x0b, 0xce, 0x1a, 0x58, 0xcb, 0x4e, 0x5c, 0xdb, 0xbc, 0xb0, 0xd3, 0x0a, 0x49, - 0x14, 0xd1, 0x29, 0xf5, 0xa8, 0x21, 0x8e, 0x67, 0x87, 0x05, 0x85, 0xe2, 0x15, 0xd2, 0xe1, 0xb2, - 0xf9, 0x29, 0x28, 0xf3, 0x35, 0x17, 0x84, 0xe2, 0x23, 0xa9, 0x77, 0x5b, 0x11, 0xed, 0x58, 0x61, - 0x20, 0x1b, 0x06, 0x99, 0xcc, 0xa5, 0x32, 0x88, 0x9a, 0x09, 0x40, 0xbf, 0xfb, 0x75, 0xd6, 0x82, - 0x05, 0xc4, 0x8e, 0x12, 0xdd, 0x59, 0x0d, 0x09, 0x9b, 0x0f, 0xf5, 0x8b, 0x2e, 0xf1, 0xea, 0x11, - 0xdd, 0xd6, 0x39, 0xbe, 0x1f, 0xc4, 0x62, 0x87, 0x66, 0x6c, 0xeb, 0x66, 0x74, 0x33, 0x36, 0x71, - 0x28, 0x53, 0xcf, 0x59, 0x27, 0x1e, 0x1f, 0x51, 0xc1, 0x74, 0x89, 0xb5, 0x60, 0x01, 0xb1, 0x6f, - 0x17, 0xd8, 0x06, 0x52, 0x49, 0x34, 0x72, 0x1c, 0xde, 0x87, 0x30, 0xa1, 0x02, 0x56, 0xf3, 0x93, - 0xc7, 0xa4, 0xb7, 0x07, 0xe2, 0xb5, 0x94, 0x16, 0xc0, 0xb9, 0x72, 0xdd, 0xdb, 0x0b, 0xf1, 0xa1, - 0x22, 0x4c, 0x26, 0x1f, 0xe8, 0x52, 0x22, 0x74, 0xcb, 0x6b, 0x30, 0x4a, 0xfb, 0xa3, 0x0c, 0x7c, - 0x6c, 0xe2, 0xf5, 0x90, 0xc3, 0x85, 0xa3, 0x94, 0xc3, 0xa6, 0x9a, 0x28, 0xee, 0xa3, 0x26, 0x9e, - 0x50, 0xa3, 0x3e, 0x90, 0x92, 0x79, 0x49, 0x55, 0x79, 0x0e, 0x06, 0xa2, 0x98, 0xb4, 0x26, 0x4a, - 0x49, 0x31, 0x5b, 0x8d, 0x49, 0x0b, 0x33, 0x08, 0x7a, 0x3b, 0x8c, 0xc7, 0x4e, 0xd8, 0x20, 0x71, - 0x48, 0xb6, 0x5d, 0xe6, 0xbb, 0x64, 0xfb, 0xd9, 0xca, 0xec, 0x29, 0x6a, 0x75, 0xad, 0x31, 0x10, - 0x96, 0x20, 0x9c, 0xc6, 0xb5, 0xff, 0x7b, 0x01, 0x1e, 0x4c, 0x7e, 0x02, 0xad, 0x18, 0xdf, 0x99, - 0x50, 0x8c, 0x6f, 0x35, 0x15, 0xe3, 0x9d, 0xdd, 0xc9, 0x87, 0x7b, 0x3c, 0xf6, 0x3d, 0xa3, 0x37, - 0xd1, 0x42, 0xea, 0x23, 0x4c, 0x27, 0x3f, 0xc2, 0x9d, 0xdd, 0xc9, 0x47, 0x7b, 0xbc, 0x63, 0xea, - 0x2b, 0x3d, 0x01, 0x83, 0x21, 0x71, 0xa2, 0xc0, 0x17, 0xdf, 0x49, 0x7d, 0x4d, 0xcc, 0x5a, 0xb1, - 0x80, 0xda, 0xdf, 0xa8, 0xa4, 0x07, 0x7b, 0x81, 0xfb, 0x63, 0x83, 0x10, 0xb9, 0x30, 0xc0, 0x76, - 0x6d, 0x5c, 0xb2, 0x5c, 0x39, 0xdc, 0x2a, 0xa4, 0x5a, 0x44, 0x91, 0x9e, 0x2d, 0xd3, 0xaf, 0x46, - 0x9b, 0x30, 0x63, 0x81, 0x76, 0xa0, 0x5c, 0x93, 0x9b, 0xa9, 0x42, 0x1e, 0x6e, 0x47, 0xb1, 0x95, - 0xd2, 0x1c, 0x47, 0xa8, 0xb8, 0x57, 0x3b, 0x30, 0xc5, 0x0d, 0x11, 0x28, 0x36, 0xdc, 0x58, 0x7c, - 0xd6, 0x43, 0x6e, 0x97, 0x17, 0x5c, 0xe3, 0x15, 0x87, 0xa8, 0x0e, 0x5a, 0x70, 0x63, 0x4c, 0xe9, - 0xa3, 0x8f, 0x59, 0x30, 0x1c, 0xd5, 0x9a, 0xab, 0x61, 0xb0, 0xed, 0xd6, 0x49, 0x28, 0x6c, 0xcc, - 0x43, 0x4a, 0xb6, 0xea, 0xdc, 0xb2, 0x24, 0xa8, 0xf9, 0x72, 0xf7, 0x85, 0x86, 0x60, 0x93, 0x2f, - 0xdd, 0x7b, 0x3d, 0x28, 0xde, 0x7d, 0x9e, 0xd4, 0xd8, 0x8a, 0x93, 0x7b, 0x66, 0x36, 0x53, 0x0e, - 0x6d, 0x73, 0xcf, 0xb7, 0x6b, 0x5b, 0x74, 0xbd, 0xe9, 0x0e, 0x3d, 0x7c, 0x7b, 0x77, 0xf2, 0xc1, - 0xb9, 0x6c, 0x9e, 0xb8, 0x57, 0x67, 0xd8, 0x80, 0xb5, 0xda, 0x9e, 0x87, 0xc9, 0xab, 0x6d, 0xc2, - 0x3c, 0x62, 0x39, 0x0c, 0xd8, 0xaa, 0x26, 0x98, 0x1a, 0x30, 0x03, 0x82, 0x4d, 0xbe, 0xe8, 0x55, - 0x18, 0x6c, 0x3a, 0x71, 0xe8, 0xee, 0x08, 0x37, 0xd8, 0x21, 0x77, 0x41, 0xcb, 0x8c, 0x96, 0x66, - 0xce, 0x14, 0x3d, 0x6f, 0xc4, 0x82, 0x11, 0x6a, 0x42, 0xa9, 0x49, 0xc2, 0x06, 0x99, 0x28, 0xe7, - 0xe1, 0xf2, 0x5f, 0xa6, 0xa4, 0x34, 0xc3, 0x0a, 0x35, 0xae, 0x58, 0x1b, 0xe6, 0x5c, 0xd0, 0xcb, - 0x50, 0x8e, 0x88, 0x47, 0x6a, 0xd4, 0x3c, 0xaa, 0x30, 0x8e, 0x3f, 0xd2, 0xa7, 0xa9, 0x48, 0xed, - 0x92, 0xaa, 0x78, 0x94, 0x2f, 0x30, 0xf9, 0x0f, 0x2b, 0x92, 0x74, 0x00, 0x5b, 0x5e, 0xbb, 0xe1, - 0xfa, 0x13, 0x90, 0xc7, 0x00, 0xae, 0x32, 0x5a, 0xa9, 0x01, 0xe4, 0x8d, 0x58, 0x30, 0xb2, 0xff, - 0x9b, 0x05, 0x28, 0x29, 0xd4, 0x8e, 0xc1, 0x26, 0x7e, 0x35, 0x69, 0x13, 0x2f, 0xe5, 0x69, 0xb4, - 0xf4, 0x30, 0x8b, 0x7f, 0xb3, 0x02, 0x29, 0x75, 0x70, 0x95, 0x44, 0x31, 0xa9, 0xbf, 0x21, 0xc2, - 0xdf, 0x10, 0xe1, 0x6f, 0x88, 0x70, 0x25, 0xc2, 0xd7, 0x53, 0x22, 0xfc, 0x1d, 0xc6, 0xaa, 0xd7, - 0xe7, 0xeb, 0xaf, 0xa8, 0x03, 0x78, 0xb3, 0x07, 0x06, 0x02, 0x95, 0x04, 0x97, 0xab, 0x2b, 0x57, - 0x33, 0x65, 0xf6, 0x2b, 0x49, 0x99, 0x7d, 0x58, 0x16, 0x7f, 0x1b, 0xa4, 0xf4, 0xef, 0x5b, 0xf0, - 0x96, 0xa4, 0xf4, 0x92, 0x33, 0x67, 0xb1, 0xe1, 0x07, 0x21, 0x99, 0x77, 0x37, 0x36, 0x48, 0x48, - 0xfc, 0x1a, 0x89, 0x94, 0x6f, 0xc7, 0xea, 0xe5, 0xdb, 0x41, 0xcf, 0xc2, 0xc8, 0xcd, 0x28, 0xf0, - 0x57, 0x03, 0xd7, 0x17, 0x22, 0x88, 0xee, 0x38, 0x4e, 0xdc, 0xde, 0x9d, 0x1c, 0xa1, 0x23, 0x2a, - 0xdb, 0x71, 0x02, 0x0b, 0xcd, 0xc1, 0xc9, 0x9b, 0xaf, 0xae, 0x3a, 0xb1, 0xe1, 0x4d, 0x90, 0xfb, - 0x7e, 0x76, 0x1e, 0x75, 0xf9, 0xc5, 0x14, 0x10, 0x77, 0xe3, 0xdb, 0xff, 0xa0, 0x00, 0x0f, 0xa5, - 0x5e, 0x24, 0xf0, 0xbc, 0xa0, 0x1d, 0xd3, 0x3d, 0x11, 0xfa, 0xa2, 0x05, 0x27, 0x9a, 0x49, 0x87, - 0x45, 0x24, 0xdc, 0xdd, 0xef, 0xca, 0x4d, 0x47, 0xa4, 0x3c, 0x22, 0xb3, 0x13, 0x62, 0x84, 0x4e, - 0xa4, 0x00, 0x11, 0xee, 0xea, 0x0b, 0x7a, 0x19, 0x2a, 0x4d, 0x67, 0xe7, 0x5a, 0xab, 0xee, 0xc4, - 0x72, 0x3b, 0xda, 0xdb, 0x8b, 0xd0, 0x8e, 0x5d, 0x6f, 0x8a, 0x47, 0x6e, 0x4c, 0x2d, 0xfa, 0xf1, - 0x4a, 0x58, 0x8d, 0x43, 0xd7, 0x6f, 0x70, 0x27, 0xe7, 0xb2, 0x24, 0x83, 0x35, 0x45, 0xfb, 0x0b, - 0x56, 0x5a, 0x49, 0xa9, 0xd1, 0x09, 0x9d, 0x98, 0x34, 0x3a, 0xe8, 0xfd, 0x50, 0xa2, 0xfb, 0x46, - 0x39, 0x2a, 0x37, 0xf2, 0xd4, 0x9c, 0xc6, 0x97, 0xd0, 0x4a, 0x94, 0xfe, 0x8b, 0x30, 0x67, 0x6a, - 0x7f, 0xb1, 0x92, 0x36, 0x16, 0xd8, 0xd9, 0xfc, 0x79, 0x80, 0x46, 0xb0, 0x46, 0x9a, 0x2d, 0x8f, - 0x0e, 0x8b, 0xc5, 0x0e, 0x78, 0x94, 0xab, 0x64, 0x41, 0x41, 0xb0, 0x81, 0x85, 0x7e, 0xde, 0x02, - 0x68, 0xc8, 0x39, 0x2f, 0x0d, 0x81, 0x6b, 0x79, 0xbe, 0x8e, 0x5e, 0x51, 0xba, 0x2f, 0x8a, 0x21, - 0x36, 0x98, 0xa3, 0x9f, 0xb1, 0xa0, 0x1c, 0xcb, 0xee, 0x73, 0xd5, 0xb8, 0x96, 0x67, 0x4f, 0xe4, - 0x4b, 0x6b, 0x9b, 0x48, 0x0d, 0x89, 0xe2, 0x8b, 0x7e, 0xd6, 0x02, 0x88, 0x3a, 0x7e, 0x6d, 0x35, - 0xf0, 0xdc, 0x5a, 0x47, 0x68, 0xcc, 0xeb, 0xb9, 0xba, 0x73, 0x14, 0xf5, 0xd9, 0x31, 0x3a, 0x1a, - 0xfa, 0x3f, 0x36, 0x38, 0xa3, 0x0f, 0x42, 0x39, 0x12, 0xd3, 0x4d, 0xe8, 0xc8, 0xb5, 0x7c, 0x9d, - 0x4a, 0x9c, 0xb6, 0x10, 0xaf, 0xe2, 0x1f, 0x56, 0x3c, 0xd1, 0x2f, 0x5a, 0x30, 0xde, 0x4a, 0xba, - 0x09, 0x85, 0x3a, 0xcc, 0x4f, 0x06, 0xa4, 0xdc, 0x90, 0xdc, 0xdb, 0x92, 0x6a, 0xc4, 0xe9, 0x5e, - 0x50, 0x09, 0xa8, 0x67, 0xf0, 0x4a, 0x8b, 0xbb, 0x2c, 0x87, 0xb4, 0x04, 0x5c, 0x48, 0x03, 0x71, - 0x37, 0x3e, 0x5a, 0x85, 0xd3, 0xb4, 0x77, 0x1d, 0x6e, 0x7e, 0x4a, 0xf5, 0x12, 0x31, 0x65, 0x58, - 0x9e, 0x7d, 0x44, 0xcc, 0x10, 0x76, 0xd6, 0x91, 0xc6, 0xc1, 0x99, 0x4f, 0xa2, 0x3f, 0xb4, 0xe0, - 0x11, 0x97, 0xa9, 0x01, 0xd3, 0x61, 0xaf, 0x35, 0x82, 0x38, 0x68, 0x27, 0xb9, 0xca, 0x8a, 0x5e, - 0xea, 0x67, 0xf6, 0xcd, 0xe2, 0x0d, 0x1e, 0x59, 0xdc, 0xa3, 0x4b, 0x78, 0xcf, 0x0e, 0xa3, 0x1f, - 0x85, 0x51, 0xb9, 0x2e, 0x56, 0xa9, 0x08, 0x66, 0x8a, 0xb6, 0x32, 0x7b, 0xf2, 0xf6, 0xee, 0xe4, - 0xe8, 0x9a, 0x09, 0xc0, 0x49, 0x3c, 0xfb, 0xdf, 0x15, 0x13, 0xa7, 0x44, 0xca, 0x87, 0xc9, 0xc4, - 0x4d, 0x4d, 0xfa, 0x7f, 0xa4, 0xf4, 0xcc, 0x55, 0xdc, 0x28, 0xef, 0x92, 0x16, 0x37, 0xaa, 0x29, - 0xc2, 0x06, 0x73, 0x6a, 0x94, 0x9e, 0x74, 0xd2, 0x9e, 0x52, 0x21, 0x01, 0x5f, 0xce, 0xb3, 0x4b, - 0xdd, 0x67, 0x7a, 0x0f, 0x89, 0xae, 0x9d, 0xec, 0x02, 0xe1, 0xee, 0x2e, 0xa1, 0x0f, 0x40, 0x25, - 0x54, 0x91, 0x2d, 0xc5, 0x3c, 0xb6, 0x6a, 0x72, 0xda, 0x88, 0xee, 0xa8, 0x03, 0x20, 0x1d, 0xc3, - 0xa2, 0x39, 0xda, 0x7f, 0x90, 0x3c, 0x18, 0x33, 0x64, 0x47, 0x1f, 0x87, 0x7e, 0x9f, 0xb6, 0x60, - 0x38, 0x0c, 0x3c, 0xcf, 0xf5, 0x1b, 0x54, 0xce, 0x09, 0x65, 0xfd, 0x9e, 0x23, 0xd1, 0x97, 0x42, - 0xa0, 0x31, 0xcb, 0x1a, 0x6b, 0x9e, 0xd8, 0xec, 0x80, 0xfd, 0x67, 0x16, 0x4c, 0xf4, 0x92, 0xc7, - 0x88, 0xc0, 0xc3, 0x52, 0xd8, 0xa8, 0xa1, 0x58, 0xf1, 0xe7, 0x89, 0x47, 0x94, 0xdb, 0xbc, 0x3c, - 0xfb, 0xb8, 0x78, 0xcd, 0x87, 0x57, 0x7b, 0xa3, 0xe2, 0xbd, 0xe8, 0xa0, 0x97, 0xe0, 0x84, 0xf1, - 0x5e, 0x91, 0x1a, 0x98, 0xca, 0xec, 0x14, 0x35, 0x80, 0x66, 0x52, 0xb0, 0x3b, 0xbb, 0x93, 0x0f, - 0xa4, 0xdb, 0x84, 0xc2, 0xe8, 0xa2, 0x63, 0x7f, 0xa5, 0x90, 0xfe, 0x5a, 0x4a, 0xd7, 0xbf, 0x6e, - 0x75, 0x79, 0x13, 0xde, 0x75, 0x14, 0xfa, 0x95, 0xf9, 0x1d, 0x54, 0x18, 0x46, 0x6f, 0x9c, 0x7b, - 0x78, 0x6c, 0x6f, 0xff, 0xfb, 0x01, 0xd8, 0xa3, 0x67, 0x7d, 0x18, 0xef, 0x07, 0x3e, 0x47, 0xfd, - 0xa4, 0xa5, 0x0e, 0xcc, 0xf8, 0x1a, 0xae, 0x1f, 0xd5, 0xd8, 0xf3, 0xfd, 0x53, 0xc4, 0x43, 0x47, - 0x94, 0x17, 0x3d, 0x79, 0x34, 0x87, 0xbe, 0x64, 0x25, 0x8f, 0xfc, 0x78, 0x50, 0xa3, 0x7b, 0x64, - 0x7d, 0x32, 0xce, 0x11, 0x79, 0xc7, 0xf4, 0xe9, 0x53, 0xaf, 0x13, 0xc6, 0x29, 0x80, 0x0d, 0xd7, - 0x77, 0x3c, 0xf7, 0x35, 0xba, 0x3b, 0x2a, 0x31, 0x05, 0xcf, 0x2c, 0xa6, 0x8b, 0xaa, 0x15, 0x1b, - 0x18, 0x67, 0xff, 0x7f, 0x18, 0x36, 0xde, 0x3c, 0x23, 0xe2, 0xe5, 0xb4, 0x19, 0xf1, 0x52, 0x31, - 0x02, 0x55, 0xce, 0xbe, 0x03, 0x4e, 0xa4, 0x3b, 0x78, 0x90, 0xe7, 0xed, 0xff, 0x3d, 0x94, 0x3e, - 0x83, 0x5b, 0x23, 0x61, 0x93, 0x76, 0xed, 0x0d, 0xc7, 0xd6, 0x1b, 0x8e, 0xad, 0x37, 0x1c, 0x5b, - 0xe6, 0xd9, 0x84, 0x70, 0xda, 0x0c, 0x1d, 0x93, 0xd3, 0x26, 0xe1, 0x86, 0x2a, 0xe7, 0xee, 0x86, - 0xb2, 0x3f, 0xd6, 0xe5, 0xb9, 0x5f, 0x0b, 0x09, 0x41, 0x01, 0x94, 0xfc, 0xa0, 0x4e, 0xa4, 0x8d, - 0x7b, 0x39, 0x1f, 0x83, 0xed, 0x6a, 0x50, 0x37, 0xc2, 0xc5, 0xe9, 0xbf, 0x08, 0x73, 0x3e, 0xf6, - 0x47, 0x07, 0x21, 0x61, 0x4e, 0xf2, 0xef, 0xfe, 0x43, 0x30, 0x14, 0x92, 0x56, 0x70, 0x0d, 0x2f, - 0x09, 0x5d, 0xa6, 0x33, 0x4a, 0x78, 0x33, 0x96, 0x70, 0xaa, 0xf3, 0x5a, 0x4e, 0xbc, 0x29, 0x94, - 0x99, 0xd2, 0x79, 0xab, 0x4e, 0xbc, 0x89, 0x19, 0x04, 0xbd, 0x03, 0xc6, 0xe2, 0xc4, 0x51, 0xb8, - 0x38, 0xf2, 0x7d, 0x40, 0xe0, 0x8e, 0x25, 0x0f, 0xca, 0x71, 0x0a, 0x1b, 0xbd, 0x0a, 0x03, 0x9b, - 0xc4, 0x6b, 0x8a, 0x4f, 0x5f, 0xcd, 0x4f, 0xd7, 0xb0, 0x77, 0xbd, 0x44, 0xbc, 0x26, 0x97, 0x84, - 0xf4, 0x17, 0x66, 0xac, 0xe8, 0xbc, 0xaf, 0x6c, 0xb5, 0xa3, 0x38, 0x68, 0xba, 0xaf, 0x49, 0x4f, - 0xe7, 0xbb, 0x72, 0x66, 0x7c, 0x45, 0xd2, 0xe7, 0x2e, 0x25, 0xf5, 0x17, 0x6b, 0xce, 0xac, 0x1f, - 0x75, 0x37, 0x64, 0x53, 0xa6, 0x23, 0x1c, 0x96, 0x79, 0xf7, 0x63, 0x5e, 0xd2, 0xe7, 0xfd, 0x50, - 0x7f, 0xb1, 0xe6, 0x8c, 0x3a, 0x6a, 0xfd, 0x0d, 0xb3, 0x3e, 0x5c, 0xcb, 0xb9, 0x0f, 0x7c, 0xed, - 0x65, 0xae, 0xc3, 0xc7, 0xa1, 0x54, 0xdb, 0x74, 0xc2, 0x78, 0x62, 0x84, 0x4d, 0x1a, 0x35, 0x8b, - 0xe7, 0x68, 0x23, 0xe6, 0x30, 0xf4, 0x28, 0x14, 0x43, 0xb2, 0xc1, 0xa2, 0x93, 0x8d, 0xb8, 0x28, - 0x4c, 0x36, 0x30, 0x6d, 0x57, 0x76, 0xd9, 0x58, 0xcf, 0x80, 0xb9, 0x5f, 0x29, 0x24, 0x0d, 0xbb, - 0xe4, 0xc8, 0xf0, 0xf5, 0x50, 0x6b, 0x87, 0x91, 0x74, 0x90, 0x19, 0xeb, 0x81, 0x35, 0x63, 0x09, - 0x47, 0x1f, 0xb6, 0x60, 0xe8, 0x66, 0x14, 0xf8, 0x3e, 0x89, 0x85, 0x12, 0xbd, 0x9e, 0xf3, 0x60, - 0x5d, 0xe6, 0xd4, 0x75, 0x1f, 0x44, 0x03, 0x96, 0x7c, 0x69, 0x77, 0xc9, 0x4e, 0xcd, 0x6b, 0xd7, - 0xbb, 0x82, 0x61, 0x2e, 0xf0, 0x66, 0x2c, 0xe1, 0x14, 0xd5, 0xf5, 0x39, 0xea, 0x40, 0x12, 0x75, - 0xd1, 0x17, 0xa8, 0x02, 0x6e, 0xff, 0x7a, 0x19, 0xce, 0x64, 0x2e, 0x1f, 0x6a, 0x72, 0x31, 0xa3, - 0xe6, 0xa2, 0xeb, 0x11, 0x19, 0x06, 0xc6, 0x4c, 0xae, 0xeb, 0xaa, 0x15, 0x1b, 0x18, 0xe8, 0xa7, - 0x01, 0x5a, 0x4e, 0xe8, 0x34, 0x89, 0x72, 0x60, 0x1f, 0xda, 0xb2, 0xa1, 0xfd, 0x58, 0x95, 0x34, - 0xf5, 0x26, 0x5e, 0x35, 0x45, 0xd8, 0x60, 0x89, 0x9e, 0x83, 0xe1, 0x90, 0x78, 0xc4, 0x89, 0x58, - 0xf8, 0x7b, 0x3a, 0x97, 0x07, 0x6b, 0x10, 0x36, 0xf1, 0xd0, 0x13, 0x2a, 0x62, 0x2e, 0x15, 0x39, - 0x94, 0x8c, 0x9a, 0x43, 0x9f, 0xb1, 0x60, 0x6c, 0xc3, 0xf5, 0x88, 0xe6, 0x2e, 0x32, 0x6f, 0x56, - 0x0e, 0xff, 0x92, 0x17, 0x4d, 0xba, 0x5a, 0x86, 0x26, 0x9a, 0x23, 0x9c, 0x62, 0x4f, 0x3f, 0xf3, - 0x36, 0x09, 0x99, 0xf0, 0x1d, 0x4c, 0x7e, 0xe6, 0xeb, 0xbc, 0x19, 0x4b, 0x38, 0x9a, 0x81, 0xf1, - 0x96, 0x13, 0x45, 0x73, 0x21, 0xa9, 0x13, 0x3f, 0x76, 0x1d, 0x8f, 0xe7, 0xc5, 0x94, 0x75, 0x38, - 0xf9, 0x6a, 0x12, 0x8c, 0xd3, 0xf8, 0xe8, 0xdd, 0xf0, 0x20, 0xf7, 0x10, 0x2d, 0xbb, 0x51, 0xe4, - 0xfa, 0x0d, 0x3d, 0x0d, 0x84, 0xa3, 0x6c, 0x52, 0x90, 0x7a, 0x70, 0x31, 0x1b, 0x0d, 0xf7, 0x7a, - 0x1e, 0x3d, 0x05, 0xe5, 0x68, 0xcb, 0x6d, 0xcd, 0x85, 0xf5, 0x88, 0x9d, 0x0e, 0x95, 0xb5, 0x5b, - 0xb6, 0x2a, 0xda, 0xb1, 0xc2, 0x40, 0x35, 0x18, 0xe1, 0x9f, 0x84, 0x87, 0xfc, 0x09, 0x09, 0xfa, - 0x74, 0x4f, 0x45, 0x2e, 0xd2, 0x3c, 0xa7, 0xb0, 0x73, 0xeb, 0x82, 0x3c, 0xab, 0xe2, 0x47, 0x2b, - 0xd7, 0x0d, 0x32, 0x38, 0x41, 0x34, 0xb9, 0xa7, 0x1b, 0xee, 0x63, 0x4f, 0xf7, 0x1c, 0x0c, 0x6f, - 0xb5, 0xd7, 0x89, 0x18, 0x79, 0x21, 0xd8, 0xd4, 0xec, 0xbb, 0xa2, 0x41, 0xd8, 0xc4, 0x63, 0xd1, - 0x96, 0x2d, 0x57, 0xfc, 0x8b, 0x26, 0x46, 0x8d, 0x68, 0xcb, 0xd5, 0x45, 0xd9, 0x8c, 0x4d, 0x1c, - 0xda, 0x35, 0x3a, 0x16, 0x6b, 0x24, 0x62, 0xc9, 0x14, 0x74, 0xb8, 0x54, 0xd7, 0xaa, 0x12, 0x80, - 0x35, 0x0e, 0x5a, 0x85, 0xd3, 0xf4, 0x4f, 0x95, 0xa5, 0xb9, 0x5e, 0x77, 0x3c, 0xb7, 0xce, 0x43, - 0xff, 0xc6, 0x93, 0xfe, 0xcd, 0x6a, 0x06, 0x0e, 0xce, 0x7c, 0xd2, 0xfe, 0xa5, 0x42, 0xd2, 0x73, - 0x62, 0x8a, 0x30, 0x14, 0x51, 0x41, 0x15, 0x5f, 0x77, 0x42, 0x69, 0xf0, 0x1c, 0x32, 0xb9, 0x49, - 0xd0, 0xbd, 0xee, 0x84, 0xa6, 0xc8, 0x63, 0x0c, 0xb0, 0xe4, 0x84, 0x6e, 0xc2, 0x40, 0xec, 0x39, - 0x39, 0x65, 0x43, 0x1a, 0x1c, 0xb5, 0x23, 0x6b, 0x69, 0x26, 0xc2, 0x8c, 0x07, 0x7a, 0x84, 0xee, - 0xde, 0xd6, 0xe5, 0x49, 0x9b, 0xd8, 0x70, 0xad, 0x47, 0x98, 0xb5, 0xda, 0x7f, 0x3e, 0x9c, 0xa1, - 0x75, 0x94, 0x21, 0x80, 0xce, 0x03, 0xd0, 0x49, 0xb3, 0x1a, 0x92, 0x0d, 0x77, 0x47, 0x18, 0x62, - 0x4a, 0xb2, 0x5d, 0x55, 0x10, 0x6c, 0x60, 0xc9, 0x67, 0xaa, 0xed, 0x0d, 0xfa, 0x4c, 0xa1, 0xfb, - 0x19, 0x0e, 0xc1, 0x06, 0x16, 0x7a, 0x16, 0x06, 0xdd, 0xa6, 0xd3, 0x50, 0x81, 0xc0, 0x8f, 0x50, - 0x91, 0xb6, 0xc8, 0x5a, 0xee, 0xec, 0x4e, 0x8e, 0xa9, 0x0e, 0xb1, 0x26, 0x2c, 0x70, 0xd1, 0x57, - 0x2c, 0x18, 0xa9, 0x05, 0xcd, 0x66, 0xe0, 0xf3, 0xed, 0xb3, 0xf0, 0x05, 0xdc, 0x3c, 0x2a, 0x33, - 0x69, 0x6a, 0xce, 0x60, 0xc6, 0x9d, 0x01, 0x2a, 0x6d, 0xd3, 0x04, 0xe1, 0x44, 0xaf, 0x4c, 0xc9, - 0x57, 0xda, 0x47, 0xf2, 0xfd, 0x86, 0x05, 0x27, 0xf9, 0xb3, 0xc6, 0xae, 0x5e, 0x64, 0x28, 0x06, - 0x47, 0xfc, 0x5a, 0x5d, 0x8e, 0x0e, 0xe5, 0xec, 0xed, 0x82, 0xe3, 0xee, 0x4e, 0xa2, 0x05, 0x38, - 0xb9, 0x11, 0x84, 0x35, 0x62, 0x0e, 0x84, 0x10, 0xdb, 0x8a, 0xd0, 0xc5, 0x34, 0x02, 0xee, 0x7e, - 0x06, 0x5d, 0x87, 0x07, 0x8c, 0x46, 0x73, 0x1c, 0xb8, 0xe4, 0x7e, 0x4c, 0x50, 0x7b, 0xe0, 0x62, - 0x26, 0x16, 0xee, 0xf1, 0x74, 0x52, 0x48, 0x56, 0xfa, 0x10, 0x92, 0xaf, 0xc0, 0x43, 0xb5, 0xee, - 0x91, 0xd9, 0x8e, 0xda, 0xeb, 0x11, 0x97, 0xe3, 0xe5, 0xd9, 0x1f, 0x10, 0x04, 0x1e, 0x9a, 0xeb, - 0x85, 0x88, 0x7b, 0xd3, 0x40, 0xef, 0x87, 0x72, 0x48, 0xd8, 0x57, 0x89, 0x44, 0xba, 0xde, 0x21, - 0xbd, 0x1d, 0xda, 0x82, 0xe7, 0x64, 0xb5, 0x66, 0x12, 0x0d, 0x11, 0x56, 0x1c, 0xd1, 0x2d, 0x18, - 0x6a, 0x39, 0x71, 0x6d, 0x53, 0x24, 0xe9, 0x1d, 0xda, 0x37, 0xaf, 0x98, 0xb3, 0xa3, 0x14, 0x23, - 0xad, 0x9f, 0x33, 0xc1, 0x92, 0x1b, 0xb5, 0xd5, 0x6a, 0x41, 0xb3, 0x15, 0xf8, 0xc4, 0x8f, 0xa5, - 0x12, 0x19, 0xe3, 0xe7, 0x1d, 0xb2, 0x15, 0x1b, 0x18, 0x54, 0x23, 0x30, 0xdf, 0xdf, 0x0d, 0x37, - 0xde, 0x0c, 0xda, 0xb1, 0xdc, 0xca, 0x0a, 0x6d, 0xa2, 0x34, 0xc2, 0x52, 0x06, 0x0e, 0xce, 0x7c, - 0x32, 0xad, 0xfe, 0xc6, 0xef, 0x4e, 0xfd, 0x9d, 0xd8, 0x5f, 0xfd, 0x9d, 0x7d, 0x27, 0x9c, 0xec, - 0x12, 0x1a, 0x07, 0x72, 0xf0, 0xcd, 0xc3, 0x03, 0xd9, 0xcb, 0xf3, 0x40, 0x6e, 0xbe, 0x5f, 0x4f, - 0xc5, 0x79, 0x1b, 0x5b, 0x9e, 0x3e, 0x5c, 0xc6, 0x0e, 0x14, 0x89, 0xbf, 0x2d, 0xb4, 0xd5, 0xc5, - 0xc3, 0xcd, 0x92, 0x0b, 0xfe, 0x36, 0x97, 0x2e, 0xcc, 0x2f, 0x76, 0xc1, 0xdf, 0xc6, 0x94, 0x36, - 0xfa, 0x9c, 0x95, 0x30, 0xc8, 0xb9, 0xa3, 0xf9, 0xbd, 0x47, 0xb2, 0xc7, 0xeb, 0xdb, 0x46, 0xb7, - 0xff, 0x43, 0x01, 0xce, 0xed, 0x47, 0xa4, 0x8f, 0xe1, 0x7b, 0x1c, 0x06, 0x23, 0x16, 0xb9, 0x21, - 0xc4, 0xff, 0x30, 0x5d, 0x15, 0x3c, 0x96, 0xe3, 0x15, 0x2c, 0x40, 0xc8, 0x83, 0x62, 0xd3, 0x69, - 0x09, 0xff, 0xe3, 0xe2, 0x61, 0xf3, 0xe1, 0xe8, 0x7f, 0xc7, 0x5b, 0x76, 0x5a, 0x7c, 0x7a, 0x1a, - 0x0d, 0x98, 0xb2, 0x41, 0x31, 0x94, 0x9c, 0x30, 0x74, 0x64, 0x98, 0xc0, 0x95, 0x7c, 0xf8, 0xcd, - 0x50, 0x92, 0xfc, 0x94, 0x35, 0xd1, 0x84, 0x39, 0x33, 0xfb, 0x17, 0xcb, 0x89, 0xe4, 0x29, 0x16, - 0xfb, 0x11, 0xc1, 0xa0, 0x70, 0x3b, 0x5a, 0x79, 0xa7, 0x21, 0xf2, 0xec, 0x64, 0xb6, 0xa3, 0x17, - 0x35, 0x1e, 0x04, 0x2b, 0xf4, 0x09, 0x8b, 0x55, 0x52, 0x90, 0x19, 0x69, 0x62, 0x97, 0x7c, 0x34, - 0x85, 0x1d, 0xcc, 0xfa, 0x0c, 0xb2, 0x11, 0x9b, 0xdc, 0x45, 0x45, 0x14, 0xb6, 0x3b, 0xe8, 0xae, - 0x88, 0xc2, 0xac, 0x7d, 0x09, 0x47, 0x3b, 0x19, 0x31, 0x1e, 0x39, 0x64, 0xe3, 0xf7, 0x11, 0xd5, - 0xf1, 0x25, 0x0b, 0x4e, 0xba, 0xe9, 0xc3, 0x7a, 0xb1, 0xa7, 0xbc, 0x91, 0x8f, 0x8f, 0xb0, 0x3b, - 0x16, 0x40, 0x19, 0x0e, 0x5d, 0x20, 0xdc, 0xdd, 0x19, 0x54, 0x87, 0x01, 0xd7, 0xdf, 0x08, 0x84, - 0xb9, 0x34, 0x7b, 0xb8, 0x4e, 0x2d, 0xfa, 0x1b, 0x81, 0x5e, 0xcd, 0xf4, 0x1f, 0x66, 0xd4, 0xd1, - 0x12, 0x9c, 0x96, 0xf9, 0x33, 0x97, 0xdc, 0x28, 0x0e, 0xc2, 0xce, 0x92, 0xdb, 0x74, 0x63, 0x66, - 0xea, 0x14, 0x67, 0x27, 0xa8, 0x26, 0xc2, 0x19, 0x70, 0x9c, 0xf9, 0x14, 0x7a, 0x0d, 0x86, 0xe4, - 0x01, 0x79, 0x39, 0x8f, 0xfd, 0x79, 0xf7, 0xfc, 0x57, 0x93, 0xa9, 0x2a, 0x4e, 0xc8, 0x25, 0x43, - 0xf4, 0x71, 0x0b, 0xc6, 0xf8, 0xef, 0x4b, 0x9d, 0x3a, 0x4f, 0xd9, 0xab, 0xe4, 0x11, 0x05, 0x5f, - 0x4d, 0xd0, 0x9c, 0x45, 0xb7, 0x77, 0x27, 0xc7, 0x92, 0x6d, 0x38, 0xc5, 0xd7, 0xfe, 0xca, 0x08, - 0x74, 0x87, 0x14, 0x24, 0xe3, 0x07, 0xac, 0xe3, 0x8e, 0x1f, 0xa0, 0xbb, 0xb4, 0x48, 0x1f, 0xfd, - 0xe7, 0xb0, 0xcc, 0x04, 0x57, 0x7d, 0xac, 0xdb, 0xf1, 0x6b, 0x98, 0xf1, 0x40, 0x21, 0x0c, 0x6e, - 0x12, 0xc7, 0x8b, 0x37, 0xf3, 0x39, 0x81, 0xba, 0xc4, 0x68, 0xa5, 0xf3, 0xef, 0x78, 0x2b, 0x16, - 0x9c, 0xd0, 0x0e, 0x0c, 0x6d, 0xf2, 0xb9, 0x28, 0x36, 0x4e, 0xcb, 0x87, 0x1d, 0xdc, 0xc4, 0x04, - 0xd7, 0x33, 0x4f, 0x34, 0x60, 0xc9, 0x8e, 0xc5, 0xaa, 0x19, 0xd1, 0x34, 0x5c, 0x8a, 0xe4, 0x97, - 0x7a, 0xd8, 0x7f, 0x28, 0xcd, 0xfb, 0x60, 0x24, 0x24, 0xb5, 0xc0, 0xaf, 0xb9, 0x1e, 0xa9, 0xcf, - 0xc8, 0xd3, 0xa5, 0x83, 0x64, 0x9c, 0x31, 0xd7, 0x0c, 0x36, 0x68, 0xe0, 0x04, 0x45, 0xb6, 0xc8, - 0x54, 0x16, 0x3a, 0xfd, 0x20, 0x44, 0x9c, 0x22, 0x2c, 0xe5, 0x94, 0xf3, 0xce, 0x68, 0xf2, 0x45, - 0x96, 0x6c, 0xc3, 0x29, 0xbe, 0xe8, 0x25, 0x80, 0x60, 0x9d, 0x07, 0xa4, 0xcd, 0xc4, 0xe2, 0x48, - 0xe1, 0x20, 0xaf, 0x3a, 0xc6, 0x33, 0x57, 0x25, 0x05, 0x6c, 0x50, 0x43, 0x57, 0x00, 0xf8, 0xb2, - 0x59, 0xeb, 0xb4, 0xe4, 0xee, 0x4a, 0xa6, 0x0c, 0x42, 0x55, 0x41, 0xee, 0xec, 0x4e, 0x76, 0x3b, - 0x70, 0x59, 0xd4, 0x8d, 0xf1, 0x38, 0xfa, 0x29, 0x18, 0x8a, 0xda, 0xcd, 0xa6, 0xa3, 0x0e, 0x1c, - 0x72, 0xcc, 0x85, 0xe5, 0x74, 0x0d, 0xa9, 0xc8, 0x1b, 0xb0, 0xe4, 0x88, 0x6e, 0x52, 0xf9, 0x2e, - 0xc4, 0x13, 0x5f, 0x45, 0xdc, 0x3c, 0xe1, 0x6e, 0xb5, 0xb7, 0xc9, 0xdd, 0x06, 0xce, 0xc0, 0xb9, - 0xb3, 0x3b, 0xf9, 0x40, 0xb2, 0x7d, 0x29, 0x10, 0xd9, 0xa9, 0x99, 0x34, 0xd1, 0x65, 0x59, 0x94, - 0x8a, 0xbe, 0xb6, 0xac, 0x95, 0xf2, 0xa4, 0x2e, 0x4a, 0xc5, 0x9a, 0x7b, 0x8f, 0x99, 0xf9, 0x30, - 0x5a, 0x86, 0x53, 0xb5, 0xc0, 0x8f, 0xc3, 0xc0, 0xf3, 0x78, 0x51, 0x36, 0xbe, 0xd1, 0xe5, 0x07, - 0x12, 0x0f, 0x8b, 0x6e, 0x9f, 0x9a, 0xeb, 0x46, 0xc1, 0x59, 0xcf, 0x51, 0x83, 0x3c, 0xad, 0x1c, - 0xc6, 0x72, 0x39, 0xab, 0x4e, 0xd0, 0x14, 0x12, 0x4a, 0xf9, 0x90, 0xf7, 0x51, 0x13, 0x7e, 0xf2, - 0xc4, 0x52, 0x7c, 0xb1, 0x67, 0x61, 0x84, 0xec, 0xc4, 0x24, 0xf4, 0x1d, 0xef, 0x1a, 0x5e, 0x92, - 0xde, 0x7f, 0xb6, 0x30, 0x2f, 0x18, 0xed, 0x38, 0x81, 0x85, 0x6c, 0xe5, 0x72, 0x32, 0xd2, 0xc0, - 0xb9, 0xcb, 0x49, 0x3a, 0x98, 0xec, 0xaf, 0x15, 0x13, 0x06, 0xeb, 0x3d, 0x39, 0x1f, 0x65, 0xf5, - 0x86, 0x64, 0x61, 0x26, 0x06, 0x10, 0x1b, 0xb1, 0x3c, 0x39, 0xab, 0x7a, 0x43, 0x2b, 0x26, 0x23, - 0x9c, 0xe4, 0x8b, 0xb6, 0xa0, 0xb4, 0x19, 0x44, 0xb1, 0xdc, 0x9e, 0x1d, 0x72, 0x27, 0x78, 0x29, - 0x88, 0x62, 0x66, 0x65, 0xa9, 0xd7, 0xa6, 0x2d, 0x11, 0xe6, 0x3c, 0xe8, 0x1e, 0x3d, 0xda, 0x74, - 0xc2, 0x7a, 0x34, 0xc7, 0x8a, 0x36, 0x0c, 0x30, 0xf3, 0x4a, 0x19, 0xd3, 0x55, 0x0d, 0xc2, 0x26, - 0x9e, 0xfd, 0x17, 0x56, 0xe2, 0x88, 0xe8, 0x06, 0x8b, 0xc0, 0xdf, 0x26, 0x3e, 0x15, 0x51, 0x66, - 0xcc, 0xdf, 0x8f, 0xa6, 0xf2, 0x99, 0xdf, 0xd2, 0xab, 0x7e, 0xe2, 0x2d, 0x4a, 0x61, 0x8a, 0x91, - 0x30, 0xc2, 0x03, 0x3f, 0x64, 0x25, 0x13, 0xd3, 0x0b, 0x79, 0xec, 0xdb, 0xcc, 0xe2, 0x0c, 0xfb, - 0xe6, 0xb8, 0xdb, 0x9f, 0xb3, 0x60, 0x68, 0xd6, 0xa9, 0x6d, 0x05, 0x1b, 0x1b, 0xe8, 0x29, 0x28, - 0xd7, 0xdb, 0xa1, 0x99, 0x23, 0xaf, 0x3c, 0x3f, 0xf3, 0xa2, 0x1d, 0x2b, 0x0c, 0x3a, 0xf5, 0x37, - 0x9c, 0x9a, 0x2c, 0xd1, 0x50, 0xe4, 0x53, 0xff, 0x22, 0x6b, 0xc1, 0x02, 0x42, 0x87, 0xbf, 0xe9, - 0xec, 0xc8, 0x87, 0xd3, 0xe7, 0x53, 0xcb, 0x1a, 0x84, 0x4d, 0x3c, 0xfb, 0xdf, 0x58, 0x30, 0x31, - 0xeb, 0x44, 0x6e, 0x6d, 0xa6, 0x1d, 0x6f, 0xce, 0xba, 0xf1, 0x7a, 0xbb, 0xb6, 0x45, 0x62, 0x5e, - 0xca, 0x83, 0xf6, 0xb2, 0x1d, 0xd1, 0x15, 0xa8, 0xb6, 0xcb, 0xaa, 0x97, 0xd7, 0x44, 0x3b, 0x56, - 0x18, 0xe8, 0x35, 0x18, 0x6e, 0x39, 0x51, 0x74, 0x2b, 0x08, 0xeb, 0x98, 0x6c, 0xe4, 0x53, 0xec, - 0xa7, 0x4a, 0x6a, 0x21, 0x89, 0x31, 0xd9, 0x10, 0xd1, 0x1e, 0x9a, 0x3e, 0x36, 0x99, 0xd9, 0x3f, - 0x6f, 0xc1, 0xe9, 0x59, 0xe2, 0x84, 0x24, 0x64, 0xb5, 0x81, 0xd4, 0x8b, 0xa0, 0x57, 0xa1, 0x1c, - 0xd3, 0x16, 0xda, 0x23, 0x2b, 0xdf, 0x1e, 0xb1, 0x38, 0x8d, 0x35, 0x41, 0x1c, 0x2b, 0x36, 0xf6, - 0xa7, 0x2d, 0x78, 0x28, 0xab, 0x2f, 0x73, 0x5e, 0xd0, 0xae, 0xdf, 0x8b, 0x0e, 0xfd, 0x7d, 0x0b, - 0x46, 0xd8, 0xd9, 0xf7, 0x3c, 0x89, 0x1d, 0xd7, 0xeb, 0xaa, 0x4b, 0x68, 0xf5, 0x59, 0x97, 0xf0, - 0x1c, 0x0c, 0x6c, 0x06, 0x4d, 0x92, 0x8e, 0xdb, 0xb8, 0x14, 0x34, 0x09, 0x66, 0x10, 0xf4, 0x0c, - 0x9d, 0x84, 0xae, 0x1f, 0x3b, 0x74, 0x39, 0xca, 0xb3, 0x81, 0x71, 0x3e, 0x01, 0x55, 0x33, 0x36, - 0x71, 0xec, 0x7f, 0x5d, 0x81, 0x21, 0x11, 0x64, 0xd4, 0x77, 0x69, 0x19, 0xe9, 0xc2, 0x29, 0xf4, - 0x74, 0xe1, 0x44, 0x30, 0x58, 0x63, 0x05, 0x52, 0x85, 0x79, 0x7e, 0x25, 0x97, 0xa8, 0x34, 0x5e, - 0x73, 0x55, 0x77, 0x8b, 0xff, 0xc7, 0x82, 0x15, 0xfa, 0xac, 0x05, 0xe3, 0xb5, 0xc0, 0xf7, 0x49, - 0x4d, 0xdb, 0x8e, 0x03, 0x79, 0x04, 0x1f, 0xcd, 0x25, 0x89, 0xea, 0x63, 0xd5, 0x14, 0x00, 0xa7, - 0xd9, 0xa3, 0x17, 0x60, 0x94, 0x8f, 0xd9, 0xf5, 0xc4, 0x81, 0x86, 0x2e, 0x57, 0x67, 0x02, 0x71, - 0x12, 0x17, 0x4d, 0xf1, 0x83, 0x21, 0x51, 0x18, 0x6e, 0x50, 0xfb, 0x7d, 0x8d, 0x92, 0x70, 0x06, - 0x06, 0x0a, 0x01, 0x85, 0x64, 0x23, 0x24, 0xd1, 0xa6, 0x08, 0xc2, 0x62, 0x76, 0xeb, 0xd0, 0xdd, - 0x15, 0x85, 0xc0, 0x5d, 0x94, 0x70, 0x06, 0x75, 0xb4, 0x25, 0x7c, 0x08, 0xe5, 0x3c, 0xe4, 0xb9, - 0xf8, 0xcc, 0x3d, 0x5d, 0x09, 0x93, 0x50, 0x62, 0xaa, 0x8b, 0xd9, 0xcb, 0x45, 0x9e, 0x88, 0xc8, - 0x14, 0x1b, 0xe6, 0xed, 0x68, 0x1e, 0x4e, 0xa4, 0x8a, 0xed, 0x45, 0xe2, 0xe0, 0x41, 0x25, 0x9d, - 0xa5, 0xca, 0xf4, 0x45, 0xb8, 0xeb, 0x09, 0xd3, 0xbf, 0x34, 0xbc, 0x8f, 0x7f, 0xa9, 0xa3, 0x42, - 0x7d, 0xf9, 0x91, 0xc0, 0x8b, 0xb9, 0x0c, 0x40, 0x5f, 0x71, 0xbd, 0x9f, 0x4a, 0xc5, 0xf5, 0x8e, - 0xb2, 0x0e, 0x5c, 0xcf, 0xa7, 0x03, 0x07, 0x0f, 0xe2, 0xbd, 0x97, 0x41, 0xb9, 0xff, 0xcb, 0x02, - 0xf9, 0x5d, 0xe7, 0x9c, 0xda, 0x26, 0xa1, 0x53, 0x06, 0xbd, 0x03, 0xc6, 0x94, 0x6b, 0x82, 0x9b, - 0x44, 0x16, 0x9b, 0x35, 0xca, 0x76, 0xc6, 0x09, 0x28, 0x4e, 0x61, 0xa3, 0x69, 0xa8, 0xd0, 0x71, - 0xe2, 0x8f, 0x72, 0xbd, 0xaf, 0xdc, 0x1f, 0x33, 0xab, 0x8b, 0xe2, 0x29, 0x8d, 0x83, 0x02, 0x38, - 0xe9, 0x39, 0x51, 0xcc, 0x7a, 0x50, 0xed, 0xf8, 0xb5, 0xbb, 0x2c, 0xc9, 0xc2, 0x32, 0x9b, 0x96, - 0xd2, 0x84, 0x70, 0x37, 0x6d, 0xfb, 0x3f, 0x96, 0x60, 0x34, 0x21, 0x19, 0x0f, 0x68, 0x30, 0x3c, - 0x05, 0x65, 0xa9, 0xc3, 0xd3, 0xb5, 0xa7, 0x94, 0xa2, 0x57, 0x18, 0x54, 0x69, 0xad, 0x6b, 0xad, - 0x9a, 0x36, 0x70, 0x0c, 0x85, 0x8b, 0x4d, 0x3c, 0x26, 0x94, 0x63, 0x2f, 0x9a, 0xf3, 0x5c, 0xe2, - 0xc7, 0xbc, 0x9b, 0xf9, 0x08, 0xe5, 0xb5, 0xa5, 0xaa, 0x49, 0x54, 0x0b, 0xe5, 0x14, 0x00, 0xa7, - 0xd9, 0xa3, 0x8f, 0x5a, 0x30, 0xea, 0xdc, 0x8a, 0x74, 0x15, 0x6f, 0x11, 0xc1, 0x7b, 0x48, 0x25, - 0x95, 0x28, 0x0c, 0xce, 0xbd, 0xfa, 0x89, 0x26, 0x9c, 0x64, 0x8a, 0x5e, 0xb7, 0x00, 0x91, 0x1d, - 0x52, 0x93, 0x31, 0xc6, 0xa2, 0x2f, 0x83, 0x79, 0xec, 0xe0, 0x2f, 0x74, 0xd1, 0xe5, 0x52, 0xbd, - 0xbb, 0x1d, 0x67, 0xf4, 0x01, 0x5d, 0x06, 0x54, 0x77, 0x23, 0x67, 0xdd, 0x23, 0x73, 0x41, 0x53, - 0x66, 0xe3, 0x8a, 0xc3, 0xe9, 0xb3, 0x62, 0x9c, 0xd1, 0x7c, 0x17, 0x06, 0xce, 0x78, 0x8a, 0xcd, - 0xb2, 0x30, 0xd8, 0xe9, 0x5c, 0x0b, 0x3d, 0xa6, 0x25, 0xcc, 0x59, 0x26, 0xda, 0xb1, 0xc2, 0xb0, - 0xff, 0xb2, 0xa8, 0x96, 0xb2, 0x0e, 0xa8, 0x77, 0x8c, 0xc0, 0x5e, 0xeb, 0xee, 0x03, 0x7b, 0x75, - 0xd8, 0x51, 0x77, 0x8e, 0x79, 0x22, 0x25, 0xb5, 0x70, 0x8f, 0x52, 0x52, 0x7f, 0xc6, 0x4a, 0xd4, - 0x77, 0x1b, 0x3e, 0xff, 0x52, 0xbe, 0xc1, 0xfc, 0x53, 0x3c, 0x24, 0x2a, 0xa5, 0x57, 0x52, 0x91, - 0x70, 0x4f, 0x41, 0x79, 0xc3, 0x73, 0x58, 0x55, 0x12, 0xb6, 0x50, 0x8d, 0x70, 0xad, 0x8b, 0xa2, - 0x1d, 0x2b, 0x0c, 0x2a, 0xf5, 0x0d, 0xa2, 0x07, 0x92, 0xda, 0xff, 0xb9, 0x08, 0xc3, 0x86, 0xc6, - 0xcf, 0x34, 0xdf, 0xac, 0xfb, 0xcc, 0x7c, 0x2b, 0x1c, 0xc0, 0x7c, 0xfb, 0x69, 0xa8, 0xd4, 0xa4, - 0x36, 0xca, 0xa7, 0x5e, 0x7d, 0x5a, 0xc7, 0x69, 0x85, 0xa4, 0x9a, 0xb0, 0xe6, 0x89, 0x16, 0x12, - 0x69, 0x8f, 0x09, 0xbf, 0x40, 0x56, 0x5e, 0xa2, 0xd0, 0x68, 0xdd, 0xcf, 0xa4, 0xcf, 0xf1, 0x4b, - 0xfb, 0x9f, 0xe3, 0xdb, 0xdf, 0xb2, 0xd4, 0xc7, 0x3d, 0x86, 0xfa, 0x36, 0x37, 0x93, 0xf5, 0x6d, - 0x2e, 0xe4, 0x32, 0xcc, 0x3d, 0x0a, 0xdb, 0x5c, 0x85, 0xa1, 0xb9, 0xa0, 0xd9, 0x74, 0xfc, 0x3a, - 0xfa, 0x41, 0x18, 0xaa, 0xf1, 0x9f, 0xc2, 0x87, 0xc6, 0x4e, 0xaa, 0x05, 0x14, 0x4b, 0x18, 0x7a, - 0x04, 0x06, 0x9c, 0xb0, 0x21, 0xfd, 0x66, 0x2c, 0xa2, 0x6c, 0x26, 0x6c, 0x44, 0x98, 0xb5, 0xda, - 0xff, 0x62, 0x00, 0x58, 0x20, 0x87, 0x13, 0x92, 0xfa, 0x5a, 0xc0, 0xca, 0xcc, 0x1e, 0xe9, 0xf9, - 0xae, 0xde, 0xd4, 0xdd, 0xcf, 0x67, 0xbc, 0xc6, 0x39, 0x5f, 0xf1, 0xb8, 0xcf, 0xf9, 0xb2, 0x8f, - 0x6e, 0x07, 0xee, 0xa3, 0xa3, 0x5b, 0xfb, 0x93, 0x16, 0x20, 0x15, 0xfd, 0xa3, 0x63, 0x2b, 0xa6, - 0xa1, 0xa2, 0xe2, 0x80, 0x84, 0x01, 0xa8, 0x45, 0x84, 0x04, 0x60, 0x8d, 0xd3, 0xc7, 0x4e, 0xfe, - 0x71, 0x29, 0xbf, 0x8b, 0xc9, 0x60, 0x7e, 0x26, 0xf5, 0x85, 0x38, 0xb7, 0x7f, 0xb7, 0x00, 0x0f, - 0x70, 0xd3, 0x61, 0xd9, 0xf1, 0x9d, 0x06, 0x69, 0xd2, 0x5e, 0xf5, 0x1b, 0x2d, 0x53, 0xa3, 0x5b, - 0x48, 0x57, 0x86, 0xde, 0x1f, 0x76, 0xed, 0xf2, 0x35, 0xc7, 0x57, 0xd9, 0xa2, 0xef, 0xc6, 0x98, - 0x11, 0x47, 0x11, 0x94, 0xe5, 0x65, 0x2e, 0x42, 0x16, 0xe7, 0xc4, 0x48, 0x89, 0x25, 0xa1, 0x65, - 0x09, 0x56, 0x8c, 0xa8, 0x2a, 0xf5, 0x82, 0xda, 0x16, 0x26, 0xad, 0x20, 0xad, 0x4a, 0x97, 0x44, - 0x3b, 0x56, 0x18, 0x76, 0x13, 0xc6, 0xe5, 0x18, 0xb6, 0xae, 0x90, 0x0e, 0x26, 0x1b, 0x54, 0xff, - 0xd4, 0x64, 0x93, 0x71, 0xbf, 0x8c, 0xd2, 0x3f, 0x73, 0x26, 0x10, 0x27, 0x71, 0x65, 0xe5, 0xd9, - 0x42, 0x76, 0xe5, 0x59, 0xfb, 0x77, 0x2d, 0x48, 0x2b, 0x40, 0xa3, 0xce, 0xa6, 0xb5, 0x67, 0x9d, - 0xcd, 0x03, 0x54, 0xaa, 0xfc, 0x49, 0x18, 0x76, 0x62, 0x6a, 0xe1, 0x70, 0x6f, 0x44, 0xf1, 0xee, - 0x4e, 0xd1, 0x96, 0x83, 0xba, 0xbb, 0xe1, 0x32, 0x2f, 0x84, 0x49, 0xce, 0x7e, 0xdd, 0x82, 0xca, - 0x7c, 0xd8, 0x39, 0x78, 0x0e, 0x54, 0x77, 0x86, 0x53, 0xe1, 0x40, 0x19, 0x4e, 0x32, 0x87, 0xaa, - 0xd8, 0x2b, 0x87, 0xca, 0xfe, 0xeb, 0x01, 0x38, 0xd9, 0x95, 0xd4, 0x87, 0x9e, 0x87, 0x11, 0xf5, - 0x95, 0xa4, 0x0b, 0xb2, 0x62, 0x46, 0xc5, 0x6a, 0x18, 0x4e, 0x60, 0xf6, 0xb1, 0x54, 0x17, 0xe1, - 0x54, 0x48, 0x5e, 0x6d, 0x93, 0x36, 0x99, 0xd9, 0x88, 0x49, 0x58, 0x25, 0xb5, 0xc0, 0xaf, 0xf3, - 0x42, 0xb5, 0xc5, 0xd9, 0x07, 0x6f, 0xef, 0x4e, 0x9e, 0xc2, 0xdd, 0x60, 0x9c, 0xf5, 0x0c, 0x6a, - 0xc1, 0xa8, 0x67, 0xda, 0xce, 0x62, 0xcb, 0x76, 0x57, 0x66, 0xb7, 0x9a, 0xad, 0x89, 0x66, 0x9c, - 0x64, 0x90, 0x34, 0xc0, 0x4b, 0xf7, 0xc8, 0x00, 0xff, 0x88, 0x36, 0xc0, 0x79, 0x50, 0xcc, 0x7b, - 0x72, 0x4e, 0xea, 0xec, 0xc7, 0x02, 0x3f, 0x8c, 0x4d, 0xfd, 0x22, 0x94, 0x65, 0xc0, 0x60, 0x5f, - 0x81, 0x76, 0x26, 0x9d, 0x1e, 0xb2, 0xfd, 0x09, 0x78, 0xf3, 0x85, 0x30, 0x34, 0x06, 0xf3, 0x6a, - 0x10, 0xcf, 0x78, 0x5e, 0x70, 0x8b, 0x9a, 0x2b, 0xd7, 0x22, 0x22, 0x7c, 0x62, 0xf6, 0x9d, 0x02, - 0x64, 0x6c, 0x2f, 0xe9, 0x9a, 0xd4, 0x36, 0x52, 0x62, 0x4d, 0x1e, 0xcc, 0x4e, 0x42, 0x3b, 0x3c, - 0xa8, 0x92, 0x5b, 0x03, 0xef, 0xce, 0x7b, 0x7b, 0xac, 0xe3, 0x2c, 0x95, 0xa4, 0x54, 0xb1, 0x96, - 0xe7, 0x01, 0xb4, 0x69, 0x2b, 0xf2, 0x88, 0x54, 0xa0, 0x84, 0xb6, 0x80, 0xb1, 0x81, 0x85, 0x9e, - 0x83, 0x61, 0xd7, 0x8f, 0x62, 0xc7, 0xf3, 0x2e, 0xb9, 0x7e, 0x2c, 0xdc, 0xbe, 0xca, 0xec, 0x59, - 0xd4, 0x20, 0x6c, 0xe2, 0x9d, 0x7d, 0x9b, 0xf1, 0xfd, 0x0e, 0xf2, 0xdd, 0x37, 0xe1, 0xa1, 0x05, - 0x37, 0x56, 0xd9, 0x6f, 0x6a, 0xbe, 0x51, 0xcb, 0x55, 0xc9, 0x2a, 0xab, 0x67, 0xbe, 0xa7, 0x91, - 0x7d, 0x56, 0x48, 0x26, 0xcb, 0xa5, 0xb3, 0xcf, 0xec, 0xe7, 0xe1, 0xf4, 0x82, 0x1b, 0x5f, 0x74, - 0x3d, 0x72, 0x40, 0x26, 0xf6, 0xef, 0x0c, 0xc2, 0x88, 0x99, 0xe9, 0x7d, 0x10, 0x71, 0xfd, 0x69, - 0x6a, 0x9c, 0x8a, 0xb7, 0x73, 0xd5, 0x89, 0xee, 0x8d, 0x43, 0xa7, 0x9d, 0x67, 0x8f, 0x98, 0x61, - 0x9f, 0x6a, 0x9e, 0xd8, 0xec, 0x00, 0xba, 0x05, 0xa5, 0x0d, 0x96, 0x1d, 0x55, 0xcc, 0x23, 0x16, - 0x27, 0x6b, 0x44, 0xf5, 0x72, 0xe4, 0xf9, 0x55, 0x9c, 0x1f, 0xb5, 0x29, 0xc2, 0x64, 0x52, 0xae, - 0x11, 0xb3, 0x2e, 0x94, 0x95, 0xc2, 0xe8, 0xa5, 0x12, 0x4a, 0x77, 0xa1, 0x12, 0x12, 0x02, 0x7a, - 0xf0, 0x1e, 0x09, 0x68, 0x96, 0xe9, 0x16, 0x6f, 0x32, 0x8b, 0x57, 0x24, 0xd9, 0x0c, 0xb1, 0x41, - 0x30, 0x32, 0xdd, 0x12, 0x60, 0x9c, 0xc6, 0x47, 0x1f, 0x54, 0x22, 0xbe, 0x9c, 0x87, 0xc7, 0xdc, - 0x9c, 0xd1, 0x47, 0x2d, 0xdd, 0x3f, 0x59, 0x80, 0xb1, 0x05, 0xbf, 0xbd, 0xba, 0xb0, 0xda, 0x5e, - 0xf7, 0xdc, 0xda, 0x15, 0xd2, 0xa1, 0x22, 0x7c, 0x8b, 0x74, 0x16, 0xe7, 0xc5, 0x0a, 0x52, 0x73, - 0xe6, 0x0a, 0x6d, 0xc4, 0x1c, 0x46, 0x85, 0xd1, 0x86, 0xeb, 0x37, 0x48, 0xd8, 0x0a, 0x5d, 0xe1, - 0xcc, 0x36, 0x84, 0xd1, 0x45, 0x0d, 0xc2, 0x26, 0x1e, 0xa5, 0x1d, 0xdc, 0xf2, 0x49, 0x98, 0x36, - 0xfd, 0x57, 0x68, 0x23, 0xe6, 0x30, 0x8a, 0x14, 0x87, 0x6d, 0xe1, 0x2b, 0x32, 0x90, 0xd6, 0x68, - 0x23, 0xe6, 0x30, 0xba, 0xd2, 0xa3, 0xf6, 0x3a, 0x0b, 0x75, 0x4a, 0x65, 0xf4, 0x54, 0x79, 0x33, - 0x96, 0x70, 0x8a, 0xba, 0x45, 0x3a, 0xf3, 0x4e, 0xec, 0xa4, 0xd3, 0x1e, 0xaf, 0xf0, 0x66, 0x2c, - 0xe1, 0xac, 0x94, 0x6e, 0x72, 0x38, 0xbe, 0xe7, 0x4a, 0xe9, 0x26, 0xbb, 0xdf, 0xc3, 0xe3, 0xf0, - 0xf7, 0x0a, 0x30, 0x62, 0x06, 0x28, 0xa2, 0x46, 0xca, 0x4c, 0x5f, 0xe9, 0xaa, 0xc4, 0xfe, 0xf6, - 0xac, 0x5b, 0x4a, 0x1b, 0x6e, 0x1c, 0xb4, 0xa2, 0xa7, 0x89, 0xdf, 0x70, 0x7d, 0xc2, 0x62, 0x35, - 0x78, 0x60, 0x63, 0x22, 0xfa, 0x71, 0x2e, 0xa8, 0x93, 0xbb, 0xb1, 0xf3, 0xef, 0xc5, 0x4d, 0x2e, - 0x37, 0xe0, 0x64, 0x57, 0x7e, 0x6d, 0x1f, 0x66, 0xcf, 0xbe, 0xf5, 0x0f, 0x6c, 0x0c, 0xc3, 0x94, - 0xb0, 0x2c, 0x21, 0x37, 0x07, 0x27, 0xf9, 0xe2, 0xa5, 0x9c, 0x58, 0xba, 0xa4, 0xca, 0x99, 0x66, - 0xa7, 0x35, 0xd7, 0xd3, 0x40, 0xdc, 0x8d, 0x6f, 0x7f, 0xca, 0x82, 0xd1, 0x44, 0xca, 0x73, 0x4e, - 0x06, 0x1a, 0x5b, 0xdd, 0x01, 0x8b, 0xd1, 0x65, 0x39, 0x13, 0x45, 0xa6, 0xc0, 0xf5, 0xea, 0xd6, - 0x20, 0x6c, 0xe2, 0xd9, 0x9f, 0x2b, 0x40, 0x59, 0x86, 0x14, 0xf5, 0xd1, 0x95, 0x4f, 0x58, 0x30, - 0xaa, 0x4e, 0xc8, 0x98, 0x4b, 0xb3, 0x90, 0x47, 0x06, 0x16, 0xed, 0x81, 0x72, 0x8a, 0xf8, 0x1b, - 0x81, 0xde, 0x2d, 0x60, 0x93, 0x19, 0x4e, 0xf2, 0x46, 0xd7, 0x01, 0xa2, 0x4e, 0x14, 0x93, 0xa6, - 0xe1, 0x5c, 0xb5, 0x8d, 0x59, 0x36, 0x55, 0x0b, 0x42, 0x42, 0xe7, 0xd4, 0xd5, 0xa0, 0x4e, 0xaa, - 0x0a, 0x53, 0x9b, 0x6d, 0xba, 0x0d, 0x1b, 0x94, 0xec, 0x5f, 0x2b, 0xc0, 0x89, 0x74, 0x97, 0xd0, - 0x7b, 0x60, 0x44, 0x72, 0x37, 0x36, 0xe1, 0x32, 0x20, 0x6a, 0x04, 0x1b, 0xb0, 0x3b, 0xbb, 0x93, - 0x93, 0xdd, 0xb7, 0xec, 0x4e, 0x99, 0x28, 0x38, 0x41, 0x8c, 0x1f, 0x53, 0x8a, 0xf3, 0xf4, 0xd9, - 0xce, 0x4c, 0xab, 0x25, 0xce, 0x1a, 0x8d, 0x63, 0x4a, 0x13, 0x8a, 0x53, 0xd8, 0x68, 0x15, 0x4e, - 0x1b, 0x2d, 0x57, 0x89, 0xdb, 0xd8, 0x5c, 0x0f, 0x42, 0xb9, 0xeb, 0x7b, 0x44, 0x87, 0x5f, 0x76, - 0xe3, 0xe0, 0xcc, 0x27, 0xa9, 0x85, 0x51, 0x73, 0x5a, 0x4e, 0xcd, 0x8d, 0x3b, 0xc2, 0x5b, 0xac, - 0xe4, 0xe1, 0x9c, 0x68, 0xc7, 0x0a, 0xc3, 0xfe, 0xd5, 0x01, 0x38, 0xc1, 0xe3, 0x0d, 0x89, 0x0a, - 0xa7, 0x45, 0xef, 0x81, 0x4a, 0x14, 0x3b, 0x21, 0xdf, 0xf2, 0x5b, 0x07, 0x96, 0x01, 0x3a, 0xe1, - 0x59, 0x12, 0xc1, 0x9a, 0x1e, 0x7a, 0x89, 0x55, 0x8b, 0x72, 0xa3, 0x4d, 0x46, 0xbd, 0x70, 0x77, - 0x0e, 0x85, 0x8b, 0x8a, 0x02, 0x36, 0xa8, 0xa1, 0x1f, 0x87, 0x52, 0x6b, 0xd3, 0x89, 0xa4, 0xb7, - 0xeb, 0x09, 0xb9, 0xe0, 0x56, 0x69, 0xe3, 0x9d, 0xdd, 0xc9, 0x33, 0xe9, 0x57, 0x65, 0x00, 0xcc, - 0x1f, 0x32, 0xc5, 0xe5, 0xc0, 0xfe, 0x37, 0x9a, 0xd4, 0xc3, 0x4e, 0xf5, 0xd2, 0x4c, 0xfa, 0x0e, - 0x8c, 0x79, 0xd6, 0x8a, 0x05, 0x94, 0x2e, 0xee, 0x4d, 0xce, 0xb2, 0x4e, 0x91, 0x07, 0x93, 0xaa, - 0xfb, 0x92, 0x06, 0x61, 0x13, 0x0f, 0x7d, 0xb2, 0x3b, 0x1a, 0x75, 0xe8, 0x08, 0x52, 0x15, 0xfa, - 0x8d, 0x43, 0xbd, 0x00, 0x15, 0xd1, 0xd5, 0xb5, 0x00, 0x3d, 0x0f, 0x23, 0xdc, 0x99, 0x32, 0x1b, - 0x3a, 0x7e, 0x6d, 0x33, 0xed, 0x02, 0x59, 0x33, 0x60, 0x38, 0x81, 0x69, 0x2f, 0xc3, 0x40, 0x9f, - 0xd2, 0xaa, 0xaf, 0x9d, 0xed, 0x8b, 0x50, 0xa6, 0xe4, 0xe4, 0xf6, 0x25, 0x0f, 0x92, 0x01, 0x94, - 0xe5, 0xfd, 0x78, 0xc8, 0x86, 0xa2, 0xeb, 0xc8, 0xa8, 0x03, 0xb5, 0x84, 0x16, 0xa3, 0xa8, 0xcd, - 0xa6, 0x1d, 0x05, 0xa2, 0xc7, 0xa1, 0x48, 0x76, 0x5a, 0xe9, 0xf0, 0x82, 0x0b, 0x3b, 0x2d, 0x37, - 0x24, 0x11, 0x45, 0x22, 0x3b, 0x2d, 0x74, 0x16, 0x0a, 0x6e, 0x5d, 0xcc, 0x48, 0x10, 0x38, 0x85, - 0xc5, 0x79, 0x5c, 0x70, 0xeb, 0xf6, 0x0e, 0x54, 0xd4, 0x85, 0x7c, 0x68, 0x4b, 0xda, 0x26, 0x56, - 0x1e, 0xf1, 0xa6, 0x92, 0x6e, 0x0f, 0xab, 0xa4, 0x0d, 0xa0, 0x33, 0xe9, 0xf3, 0xd2, 0x65, 0xe7, - 0x60, 0xa0, 0x16, 0x88, 0x1a, 0x28, 0x65, 0x4d, 0x86, 0x19, 0x25, 0x0c, 0x62, 0xdf, 0x80, 0xb1, - 0x2b, 0x7e, 0x70, 0x8b, 0xdd, 0x9b, 0xc3, 0xca, 0xc4, 0x52, 0xc2, 0x1b, 0xf4, 0x47, 0xda, 0x04, - 0x66, 0x50, 0xcc, 0x61, 0xaa, 0x80, 0x65, 0xa1, 0x57, 0x01, 0x4b, 0xfb, 0x43, 0x16, 0x8c, 0xa8, - 0x94, 0xdc, 0x85, 0xed, 0x2d, 0x4a, 0xb7, 0x11, 0x06, 0xed, 0x56, 0x9a, 0x2e, 0xbb, 0xfb, 0x13, - 0x73, 0x98, 0x99, 0xab, 0x5e, 0xd8, 0x27, 0x57, 0xfd, 0x1c, 0x0c, 0x6c, 0xb9, 0x7e, 0x3d, 0xed, - 0x32, 0xbc, 0xe2, 0xfa, 0x75, 0xcc, 0x20, 0xb4, 0x0b, 0x27, 0x54, 0x17, 0xa4, 0xf1, 0xf1, 0x3c, - 0x8c, 0xac, 0xb7, 0x5d, 0xaf, 0x2e, 0xeb, 0xdf, 0xa6, 0x96, 0xcb, 0xac, 0x01, 0xc3, 0x09, 0x4c, - 0x74, 0x1e, 0x60, 0xdd, 0xf5, 0x9d, 0xb0, 0xb3, 0xaa, 0xad, 0x1d, 0xa5, 0x00, 0x67, 0x15, 0x04, - 0x1b, 0x58, 0xf6, 0x67, 0x8a, 0x30, 0x96, 0x4c, 0x4c, 0xee, 0xc3, 0x7d, 0xf0, 0x38, 0x94, 0x58, - 0xae, 0x72, 0xfa, 0xd3, 0xf2, 0x92, 0xb1, 0x1c, 0x86, 0x22, 0x18, 0xe4, 0x8b, 0x39, 0x9f, 0xfb, - 0x13, 0x55, 0x27, 0x95, 0x9f, 0x91, 0x45, 0xe5, 0x0a, 0xb7, 0xad, 0x60, 0x85, 0x3e, 0x6a, 0xc1, - 0x50, 0xd0, 0x32, 0x0b, 0x1f, 0xbe, 0x3b, 0xcf, 0xa4, 0x6d, 0x91, 0xc9, 0x29, 0x76, 0x7c, 0xea, - 0xd3, 0xcb, 0xcf, 0x21, 0x59, 0x9f, 0xfd, 0x31, 0x18, 0x31, 0x31, 0xf7, 0xdb, 0xf4, 0x95, 0xcd, - 0x4d, 0xdf, 0x27, 0xcc, 0x49, 0x21, 0xd2, 0xd2, 0xfb, 0x58, 0x6e, 0xd7, 0xa0, 0x54, 0x53, 0xa1, - 0x4b, 0x77, 0x55, 0x35, 0x5d, 0x95, 0x6d, 0x62, 0xc7, 0xc2, 0x9c, 0x9a, 0xfd, 0x2d, 0xcb, 0x98, - 0x1f, 0x98, 0x44, 0x8b, 0x75, 0x14, 0x42, 0xb1, 0xb1, 0xbd, 0x25, 0xd4, 0xfc, 0xe5, 0x9c, 0x86, - 0x77, 0x61, 0x7b, 0x4b, 0xcf, 0x71, 0xb3, 0x15, 0x53, 0x66, 0x7d, 0x38, 0xc3, 0x13, 0xd5, 0x0b, - 0x8a, 0xfb, 0x57, 0x2f, 0xb0, 0x5f, 0x2f, 0xc0, 0xc9, 0xae, 0x49, 0x85, 0x5e, 0x83, 0x52, 0x48, - 0xdf, 0x52, 0xbc, 0xde, 0x52, 0x6e, 0xf5, 0x06, 0xa2, 0xc5, 0xba, 0x56, 0x9f, 0xc9, 0x76, 0xcc, - 0x59, 0xa2, 0xcb, 0x80, 0x74, 0x80, 0x9d, 0xf2, 0xc4, 0xf3, 0x57, 0x56, 0x51, 0x38, 0x33, 0x5d, - 0x18, 0x38, 0xe3, 0x29, 0xf4, 0x42, 0xda, 0xa1, 0x5f, 0x4c, 0x9e, 0x24, 0xed, 0xe5, 0x9b, 0xb7, - 0x7f, 0xab, 0x00, 0xa3, 0x89, 0x3a, 0x94, 0xc8, 0x83, 0x32, 0xf1, 0xd8, 0x31, 0x9f, 0x54, 0x36, - 0x87, 0xbd, 0x55, 0x42, 0x29, 0xc8, 0x0b, 0x82, 0x2e, 0x56, 0x1c, 0xee, 0x8f, 0xe0, 0x9c, 0xe7, - 0x61, 0x44, 0x76, 0xe8, 0xdd, 0x4e, 0xd3, 0x13, 0x03, 0xa8, 0xe6, 0xe8, 0x05, 0x03, 0x86, 0x13, - 0x98, 0xf6, 0xef, 0x15, 0x61, 0x82, 0x9f, 0x8b, 0xd6, 0xd5, 0xcc, 0x5b, 0x96, 0xfe, 0x84, 0x5f, - 0xd0, 0xd5, 0x62, 0xad, 0x3c, 0xae, 0x4e, 0xee, 0xc5, 0xa8, 0xaf, 0x98, 0xd2, 0x2f, 0xa6, 0x62, - 0x4a, 0xf9, 0x16, 0xaf, 0x71, 0x44, 0x3d, 0xfa, 0xde, 0x0a, 0x32, 0xfd, 0x27, 0x05, 0x18, 0x4f, - 0xdd, 0x90, 0x85, 0x3e, 0x93, 0xbc, 0x54, 0xc1, 0xca, 0xe3, 0xcc, 0x68, 0xcf, 0x4b, 0x93, 0x0e, - 0x76, 0xb5, 0xc2, 0x3d, 0x5a, 0x2a, 0xf6, 0x37, 0x0b, 0x30, 0x96, 0xbc, 0xda, 0xeb, 0x3e, 0x1c, - 0xa9, 0xb7, 0x42, 0x85, 0xdd, 0x5e, 0xc3, 0x6e, 0xa4, 0xe7, 0x47, 0x4e, 0xfc, 0xa2, 0x10, 0xd9, - 0x88, 0x35, 0xfc, 0xbe, 0xb8, 0xb1, 0xc2, 0xfe, 0x67, 0x16, 0x9c, 0xe1, 0x6f, 0x99, 0x9e, 0x87, - 0x7f, 0x27, 0x6b, 0x74, 0x5f, 0xce, 0xb7, 0x83, 0xa9, 0x2a, 0xc7, 0xfb, 0x8d, 0x2f, 0xbb, 0x40, - 0x5a, 0xf4, 0x36, 0x39, 0x15, 0xee, 0xc3, 0xce, 0x1e, 0x68, 0x32, 0xd8, 0xdf, 0x2c, 0x82, 0xbe, - 0x33, 0x1b, 0xb9, 0x22, 0xeb, 0x3d, 0x97, 0x6a, 0xcf, 0xd5, 0x8e, 0x5f, 0xd3, 0xb7, 0x73, 0x97, - 0x53, 0x49, 0xef, 0x3f, 0x67, 0xc1, 0xb0, 0xeb, 0xbb, 0xb1, 0xeb, 0x30, 0x97, 0x4d, 0x3e, 0x17, - 0xdf, 0x2a, 0x76, 0x8b, 0x9c, 0x72, 0x10, 0x9a, 0xe7, 0x94, 0x8a, 0x19, 0x36, 0x39, 0xa3, 0xf7, - 0x89, 0xb4, 0x8f, 0x62, 0x6e, 0xa5, 0x23, 0xca, 0xa9, 0x5c, 0x8f, 0x16, 0x35, 0xbc, 0xe2, 0x30, - 0xa7, 0x8a, 0x2b, 0x98, 0x92, 0x52, 0x17, 0x07, 0x28, 0xd3, 0x96, 0x35, 0x63, 0xce, 0xc8, 0x8e, - 0x00, 0x75, 0x8f, 0xc5, 0x01, 0x43, 0xea, 0xa7, 0xa1, 0xe2, 0xb4, 0xe3, 0xa0, 0x49, 0x87, 0x49, - 0x1c, 0xa5, 0xea, 0xa4, 0x01, 0x09, 0xc0, 0x1a, 0xc7, 0xfe, 0x4c, 0x09, 0x52, 0x69, 0xe8, 0x68, - 0xc7, 0xbc, 0xef, 0xdd, 0xca, 0xf7, 0xbe, 0x77, 0xd5, 0x99, 0xac, 0x3b, 0xdf, 0x51, 0x43, 0x7a, - 0xbf, 0xb8, 0x8d, 0xf9, 0x62, 0xda, 0xfb, 0xf5, 0x13, 0xfd, 0x9d, 0x2a, 0xd0, 0xb9, 0x3a, 0xcd, - 0xab, 0x78, 0x4d, 0xed, 0xeb, 0x28, 0xdb, 0xef, 0xea, 0xdf, 0x0f, 0x8b, 0x6b, 0x7a, 0x30, 0x89, - 0xda, 0x5e, 0x2c, 0x66, 0xc3, 0x8b, 0x39, 0xae, 0x32, 0x4e, 0x58, 0xd7, 0x72, 0xe1, 0xff, 0xb1, - 0xc1, 0x34, 0xe9, 0xce, 0x1c, 0x3c, 0x52, 0x77, 0xe6, 0x50, 0xae, 0xee, 0xcc, 0xf3, 0x00, 0x6c, - 0x6e, 0xf3, 0xd0, 0xdf, 0x32, 0xf3, 0x32, 0x29, 0x51, 0x88, 0x15, 0x04, 0x1b, 0x58, 0xf6, 0x0f, - 0x43, 0xb2, 0x18, 0x11, 0x9a, 0x94, 0xb5, 0x8f, 0xf8, 0x89, 0x07, 0xcb, 0xba, 0x4a, 0x94, 0x29, - 0xfa, 0x0d, 0x0b, 0xcc, 0x8a, 0x49, 0xe8, 0x55, 0x5e, 0x9a, 0xc9, 0xca, 0xe3, 0x64, 0xdc, 0xa0, - 0x3b, 0xb5, 0xec, 0xb4, 0x52, 0x21, 0x1a, 0xb2, 0x3e, 0xd3, 0xd9, 0xb7, 0x41, 0x59, 0x42, 0x0f, - 0x64, 0xd4, 0x7d, 0x10, 0x4e, 0xc9, 0x0c, 0x6e, 0xe9, 0xa3, 0x17, 0xa7, 0xaa, 0xfb, 0xbb, 0x7e, - 0xa4, 0x3f, 0xa7, 0xd0, 0xcb, 0x9f, 0xd3, 0xc7, 0xad, 0xff, 0xbf, 0x69, 0xc1, 0xb9, 0x74, 0x07, - 0xa2, 0xe5, 0xc0, 0x77, 0xe3, 0x20, 0xac, 0x92, 0x38, 0x76, 0xfd, 0x06, 0xab, 0x48, 0x79, 0xcb, - 0x09, 0xe5, 0xad, 0x24, 0x4c, 0x50, 0xde, 0x70, 0x42, 0x1f, 0xb3, 0x56, 0xd4, 0x81, 0x41, 0x1e, - 0x1f, 0x2a, 0xac, 0xf5, 0x43, 0xae, 0x8d, 0x8c, 0xe1, 0xd0, 0xdb, 0x05, 0x1e, 0x9b, 0x8a, 0x05, - 0x43, 0xfb, 0x3b, 0x16, 0xa0, 0x95, 0x6d, 0x12, 0x86, 0x6e, 0xdd, 0x88, 0x68, 0x65, 0xd7, 0xdd, - 0x19, 0xd7, 0xda, 0x99, 0xf5, 0x05, 0x52, 0xd7, 0xdd, 0x19, 0xff, 0xb2, 0xaf, 0xbb, 0x2b, 0x1c, - 0xec, 0xba, 0x3b, 0xb4, 0x02, 0x67, 0x9a, 0x7c, 0xbb, 0xc1, 0xaf, 0x90, 0xe2, 0x7b, 0x0f, 0x95, - 0x0a, 0xfb, 0xd0, 0xed, 0xdd, 0xc9, 0x33, 0xcb, 0x59, 0x08, 0x38, 0xfb, 0x39, 0xfb, 0x6d, 0x80, - 0x78, 0x20, 0xeb, 0x5c, 0x56, 0x2c, 0x5e, 0x4f, 0xf7, 0x8b, 0xfd, 0x85, 0x12, 0x8c, 0xa7, 0x6a, - 0xd6, 0xd3, 0xad, 0x5e, 0x77, 0xf0, 0xdf, 0xa1, 0xf5, 0x77, 0x77, 0xf7, 0xfa, 0x0a, 0x27, 0xf4, - 0xa1, 0xe4, 0xfa, 0xad, 0x76, 0x9c, 0x4f, 0x26, 0x3e, 0xef, 0xc4, 0x22, 0x25, 0x68, 0xb8, 0x8b, - 0xe9, 0x5f, 0xcc, 0xd9, 0xe4, 0x19, 0x9c, 0x98, 0x30, 0xc6, 0x07, 0xee, 0x91, 0x3b, 0xe0, 0xc3, - 0x3a, 0x54, 0xb0, 0x94, 0x87, 0x63, 0x31, 0x35, 0x59, 0x8e, 0x3a, 0x94, 0xe4, 0x6b, 0x05, 0x18, - 0x36, 0x3e, 0x1a, 0xfa, 0x95, 0x64, 0x3d, 0x41, 0x2b, 0xbf, 0x57, 0x62, 0xf4, 0xa7, 0x74, 0xc5, - 0x40, 0xfe, 0x4a, 0x4f, 0x74, 0x97, 0x12, 0xbc, 0xb3, 0x3b, 0x79, 0x22, 0x55, 0x2c, 0x30, 0x51, - 0x5e, 0xf0, 0xec, 0x07, 0x60, 0x3c, 0x45, 0x26, 0xe3, 0x95, 0xd7, 0xcc, 0x57, 0x3e, 0xb4, 0x5b, - 0xca, 0x1c, 0xb2, 0xaf, 0xd2, 0x21, 0x13, 0x09, 0xc0, 0x81, 0x47, 0xfa, 0xf0, 0xc1, 0xa6, 0xf2, - 0xfc, 0x0b, 0x7d, 0xe6, 0xf9, 0x3f, 0x09, 0xe5, 0x56, 0xe0, 0xb9, 0x35, 0x57, 0x95, 0xf7, 0x65, - 0x95, 0x05, 0x56, 0x45, 0x1b, 0x56, 0x50, 0x74, 0x0b, 0x2a, 0x37, 0x6f, 0xc5, 0xfc, 0xf4, 0x47, - 0xf8, 0xb7, 0xf3, 0x3a, 0xf4, 0x51, 0x46, 0x8b, 0x3a, 0x5e, 0xc2, 0x9a, 0x17, 0xb2, 0x61, 0x90, - 0x29, 0x41, 0x99, 0x0c, 0xc4, 0x7c, 0xef, 0x4c, 0x3b, 0x46, 0x58, 0x40, 0xec, 0x2f, 0x57, 0xe0, - 0x74, 0xd6, 0xc5, 0x21, 0xe8, 0xfd, 0x30, 0xc8, 0xfb, 0x98, 0xcf, 0xdd, 0x54, 0x59, 0x3c, 0x16, - 0x18, 0x41, 0xd1, 0x2d, 0xf6, 0x1b, 0x0b, 0x9e, 0x82, 0xbb, 0xe7, 0xac, 0x8b, 0x19, 0x72, 0x34, - 0xdc, 0x97, 0x1c, 0xcd, 0x7d, 0xc9, 0xe1, 0xdc, 0x3d, 0x67, 0x1d, 0xed, 0x40, 0xa9, 0xe1, 0xc6, - 0xc4, 0x11, 0x4e, 0x84, 0x1b, 0x47, 0xc2, 0x9c, 0x38, 0xdc, 0x4a, 0x63, 0x3f, 0x31, 0x67, 0x88, - 0xbe, 0x64, 0xc1, 0xf8, 0x7a, 0xb2, 0xc0, 0x88, 0x10, 0x9e, 0xce, 0x11, 0x5c, 0x0e, 0x93, 0x64, - 0xc4, 0xef, 0x7b, 0x4c, 0x35, 0xe2, 0x74, 0x77, 0xd0, 0x47, 0x2c, 0x18, 0xda, 0x70, 0x3d, 0xa3, - 0xfa, 0xfe, 0x11, 0x7c, 0x9c, 0x8b, 0x8c, 0x81, 0xde, 0x71, 0xf0, 0xff, 0x11, 0x96, 0x9c, 0x7b, - 0x69, 0xaa, 0xc1, 0xc3, 0x6a, 0xaa, 0xa1, 0x7b, 0xa4, 0xa9, 0x3e, 0x6e, 0x41, 0x45, 0x8d, 0xb4, - 0x28, 0xd4, 0xf0, 0x9e, 0x23, 0xfc, 0xe4, 0xdc, 0x73, 0xa2, 0xfe, 0x62, 0xcd, 0x1c, 0x7d, 0xd6, - 0x82, 0x61, 0xe7, 0xb5, 0x76, 0x48, 0xea, 0x64, 0x3b, 0x68, 0x45, 0xa2, 0x7c, 0xe2, 0xcb, 0xf9, - 0x77, 0x66, 0x86, 0x32, 0x99, 0x27, 0xdb, 0x2b, 0xad, 0x48, 0x24, 0x2a, 0xea, 0x06, 0x6c, 0x76, - 0xc1, 0xde, 0x2d, 0xc0, 0xe4, 0x3e, 0x14, 0xd0, 0xf3, 0x30, 0x12, 0x84, 0x0d, 0xc7, 0x77, 0x5f, - 0x33, 0x2b, 0x06, 0x29, 0x2b, 0x6b, 0xc5, 0x80, 0xe1, 0x04, 0xa6, 0x59, 0x4a, 0xa2, 0xb0, 0x4f, - 0x29, 0x89, 0x73, 0x30, 0x10, 0x92, 0x56, 0x90, 0xde, 0x2c, 0xb0, 0x24, 0x21, 0x06, 0x41, 0x8f, - 0x42, 0xd1, 0x69, 0xb9, 0x22, 0xb4, 0x44, 0xed, 0x81, 0x66, 0x56, 0x17, 0x31, 0x6d, 0x4f, 0x54, - 0xb6, 0x29, 0x1d, 0x4b, 0x65, 0x1b, 0xaa, 0x06, 0xc4, 0xd9, 0xc5, 0xa0, 0x56, 0x03, 0xc9, 0x33, - 0x05, 0xfb, 0xf5, 0x22, 0x3c, 0xba, 0xe7, 0x7c, 0xd1, 0x71, 0xa6, 0xd6, 0x1e, 0x71, 0xa6, 0x72, - 0x78, 0x0a, 0xfb, 0x0d, 0x4f, 0xb1, 0xc7, 0xf0, 0x7c, 0x84, 0x2e, 0x03, 0x59, 0x69, 0x29, 0x9f, - 0xeb, 0x7e, 0x7b, 0x15, 0x6e, 0x12, 0x2b, 0x40, 0x42, 0xb1, 0xe6, 0x4b, 0xf7, 0x00, 0x89, 0x32, - 0x0a, 0xa5, 0x3c, 0xd4, 0x40, 0xcf, 0x6a, 0x47, 0x7c, 0xee, 0xf7, 0xaa, 0xcd, 0x60, 0xff, 0xf6, - 0x00, 0x3c, 0xde, 0x87, 0xf4, 0x36, 0x67, 0xb1, 0xd5, 0xe7, 0x2c, 0xfe, 0x1e, 0xff, 0x4c, 0x1f, - 0xcb, 0xfc, 0x4c, 0x38, 0xff, 0xcf, 0xb4, 0xf7, 0x17, 0x42, 0x4f, 0x41, 0xd9, 0xf5, 0x23, 0x52, - 0x6b, 0x87, 0x3c, 0xe6, 0xde, 0xc8, 0x20, 0x5c, 0x14, 0xed, 0x58, 0x61, 0xd0, 0x3d, 0x5d, 0xcd, - 0xa1, 0xcb, 0x7f, 0x28, 0xa7, 0xb4, 0x79, 0x33, 0x19, 0x91, 0x9b, 0x14, 0x73, 0x33, 0x54, 0x02, - 0x70, 0x36, 0xf6, 0xdf, 0xb5, 0xe0, 0x6c, 0x6f, 0x15, 0x8b, 0x9e, 0x81, 0xe1, 0x75, 0x16, 0xb8, - 0xc5, 0x2e, 0x7a, 0x97, 0x53, 0x87, 0xbd, 0xaf, 0x6e, 0xc6, 0x26, 0x0e, 0x9a, 0x83, 0x93, 0x66, - 0xc4, 0xd7, 0xb2, 0x11, 0x55, 0xc2, 0x9c, 0x00, 0x6b, 0x69, 0x20, 0xee, 0xc6, 0xb7, 0xbf, 0x5b, - 0xcc, 0xee, 0x16, 0x37, 0xc5, 0x0e, 0x32, 0x9b, 0xc5, 0x5c, 0x2d, 0xf4, 0x21, 0x71, 0x8b, 0xc7, - 0x2d, 0x71, 0x07, 0x7a, 0x49, 0x5c, 0x34, 0x0f, 0x27, 0x8c, 0x9b, 0xf8, 0x78, 0x21, 0x05, 0x1e, - 0x65, 0xa8, 0xaa, 0x20, 0xad, 0xa6, 0xe0, 0xb8, 0xeb, 0x89, 0xfb, 0x7c, 0xea, 0xfd, 0x6a, 0x01, - 0x1e, 0xea, 0x69, 0xfd, 0x1e, 0x93, 0x46, 0x31, 0x3f, 0xff, 0xc0, 0xf1, 0x7c, 0x7e, 0xf3, 0xa3, - 0x94, 0xf6, 0xfb, 0x28, 0xf6, 0x1f, 0x17, 0x7a, 0x2e, 0x04, 0xba, 0x13, 0xfa, 0xbe, 0x1d, 0xa5, - 0x17, 0x60, 0xd4, 0x69, 0xb5, 0x38, 0x1e, 0x8b, 0xd8, 0x4e, 0x55, 0x5d, 0x9b, 0x31, 0x81, 0x38, - 0x89, 0xdb, 0x97, 0x4d, 0xf3, 0xa7, 0x16, 0x54, 0x30, 0xd9, 0xe0, 0xd2, 0x08, 0xdd, 0x14, 0x43, - 0x64, 0xe5, 0x51, 0xf7, 0x9a, 0x0e, 0x6c, 0xe4, 0xb2, 0x7a, 0xd0, 0x59, 0x83, 0x7d, 0xd8, 0xbc, - 0x65, 0x75, 0x37, 0x5f, 0xb1, 0xf7, 0xdd, 0x7c, 0xf6, 0xb7, 0x87, 0xe8, 0xeb, 0xb5, 0x82, 0xb9, - 0x90, 0xd4, 0x23, 0xfa, 0x7d, 0xdb, 0xa1, 0x27, 0x26, 0x89, 0xfa, 0xbe, 0xd7, 0xf0, 0x12, 0xa6, - 0xed, 0x89, 0x03, 0xb2, 0xc2, 0x81, 0x6a, 0x4e, 0x15, 0xf7, 0xad, 0x39, 0xf5, 0x02, 0x8c, 0x46, - 0xd1, 0xe6, 0x6a, 0xe8, 0x6e, 0x3b, 0x31, 0xb9, 0x42, 0x3a, 0xc2, 0xf6, 0xd5, 0xf5, 0x57, 0xaa, - 0x97, 0x34, 0x10, 0x27, 0x71, 0xd1, 0x02, 0x9c, 0xd4, 0x95, 0x9f, 0x48, 0x18, 0xb3, 0x9c, 0x22, - 0x3e, 0x13, 0x54, 0xb1, 0x05, 0x5d, 0x2b, 0x4a, 0x20, 0xe0, 0xee, 0x67, 0xa8, 0x3c, 0x4d, 0x34, - 0xd2, 0x8e, 0x0c, 0x26, 0xe5, 0x69, 0x82, 0x0e, 0xed, 0x4b, 0xd7, 0x13, 0x68, 0x19, 0x4e, 0xf1, - 0x89, 0x31, 0xd3, 0x6a, 0x19, 0x6f, 0x34, 0x94, 0xac, 0x37, 0xbc, 0xd0, 0x8d, 0x82, 0xb3, 0x9e, - 0x43, 0xcf, 0xc1, 0xb0, 0x6a, 0x5e, 0x9c, 0x17, 0x67, 0x3b, 0xca, 0xb7, 0xa4, 0xc8, 0x2c, 0xd6, - 0xb1, 0x89, 0x87, 0xde, 0x0d, 0x0f, 0xea, 0xbf, 0x3c, 0xf1, 0x94, 0x1f, 0x78, 0xce, 0x8b, 0xa2, - 0x7a, 0xea, 0x9e, 0xb7, 0x85, 0x4c, 0xb4, 0x3a, 0xee, 0xf5, 0x3c, 0x5a, 0x87, 0xb3, 0x0a, 0x74, - 0xc1, 0x8f, 0x59, 0x16, 0x59, 0x44, 0x66, 0x9d, 0x88, 0x5c, 0x0b, 0x3d, 0x56, 0x86, 0xaf, 0xa2, - 0x2f, 0x0b, 0x5f, 0x70, 0xe3, 0x4b, 0x59, 0x98, 0x78, 0x09, 0xef, 0x41, 0x05, 0x4d, 0x43, 0x85, - 0xf8, 0xce, 0xba, 0x47, 0x56, 0xe6, 0x16, 0x59, 0x71, 0x3e, 0xe3, 0x7c, 0xf5, 0x82, 0x04, 0x60, - 0x8d, 0xa3, 0xe2, 0x7e, 0x47, 0x7a, 0x5e, 0x5c, 0xbf, 0x0a, 0xa7, 0x1b, 0xb5, 0x16, 0xb5, 0x08, - 0xdd, 0x1a, 0x99, 0xa9, 0xb1, 0x30, 0x47, 0xfa, 0x61, 0x78, 0x21, 0x68, 0x95, 0x40, 0xb1, 0x30, - 0xb7, 0xda, 0x85, 0x83, 0x33, 0x9f, 0x64, 0xe1, 0xb0, 0x61, 0xb0, 0xd3, 0x99, 0x38, 0x95, 0x0a, - 0x87, 0xa5, 0x8d, 0x98, 0xc3, 0xd0, 0x65, 0x40, 0x2c, 0x1b, 0xe7, 0x52, 0x1c, 0xb7, 0x94, 0x09, - 0x3a, 0x71, 0x3a, 0x59, 0x62, 0xeb, 0x62, 0x17, 0x06, 0xce, 0x78, 0x8a, 0x5a, 0x34, 0x7e, 0xc0, - 0xa8, 0x4f, 0x3c, 0x98, 0xb4, 0x68, 0xae, 0xf2, 0x66, 0x2c, 0xe1, 0xf6, 0x9f, 0x58, 0x30, 0xaa, - 0x96, 0xf6, 0x31, 0xa4, 0xcb, 0x79, 0xc9, 0x74, 0xb9, 0x85, 0xc3, 0x0b, 0x47, 0xd6, 0xf3, 0x1e, - 0x31, 0xe9, 0x5f, 0x1b, 0x06, 0xd0, 0x02, 0x54, 0xe9, 0x2e, 0xab, 0xa7, 0xee, 0xba, 0x6f, 0x85, - 0x57, 0x56, 0x31, 0xac, 0xd2, 0xbd, 0x2d, 0x86, 0x55, 0x85, 0x33, 0xd2, 0xb2, 0xe0, 0x87, 0x7d, - 0x97, 0x82, 0x48, 0xc9, 0xc2, 0xf2, 0xec, 0xa3, 0x82, 0xd0, 0x99, 0xc5, 0x2c, 0x24, 0x9c, 0xfd, - 0x6c, 0xc2, 0xa0, 0x19, 0xda, 0xd7, 0xca, 0x54, 0xcb, 0x7f, 0x69, 0x43, 0xde, 0x6e, 0x96, 0x5a, - 0xfe, 0x4b, 0x17, 0xab, 0x58, 0xe3, 0x64, 0xeb, 0x80, 0x4a, 0x4e, 0x3a, 0x00, 0x0e, 0xac, 0x03, - 0xa4, 0x34, 0x1a, 0xee, 0x29, 0x8d, 0xe4, 0xa1, 0xc2, 0x48, 0xcf, 0x43, 0x85, 0x77, 0xc0, 0x98, - 0xeb, 0x6f, 0x92, 0xd0, 0x8d, 0x49, 0x9d, 0xad, 0x05, 0x26, 0xa9, 0xca, 0xda, 0x02, 0x58, 0x4c, - 0x40, 0x71, 0x0a, 0x3b, 0x29, 0x42, 0xc7, 0xfa, 0x10, 0xa1, 0x3d, 0x14, 0xd7, 0x78, 0x3e, 0x8a, - 0xeb, 0xc4, 0xe1, 0x15, 0xd7, 0xc9, 0x23, 0x55, 0x5c, 0x28, 0x17, 0xc5, 0xd5, 0x97, 0x4e, 0x30, - 0x76, 0xa6, 0xa7, 0xf7, 0xd9, 0x99, 0xf6, 0xd2, 0x5a, 0x67, 0xee, 0x5a, 0x6b, 0x65, 0x2b, 0xa4, - 0x07, 0x8e, 0x5a, 0x21, 0x7d, 0xbc, 0x00, 0x67, 0xb4, 0xc8, 0xa6, 0x0b, 0xc5, 0xdd, 0xa0, 0x42, - 0x8b, 0xdd, 0xa5, 0xc9, 0xcf, 0xe8, 0x8c, 0xa4, 0x4b, 0x9d, 0xbf, 0xa9, 0x20, 0xd8, 0xc0, 0x62, - 0xb9, 0x8b, 0x24, 0x64, 0x85, 0xe7, 0xd3, 0xf2, 0x7c, 0x4e, 0xb4, 0x63, 0x85, 0x41, 0xa7, 0x22, - 0xfd, 0x2d, 0x72, 0xd0, 0xd3, 0x25, 0x4d, 0xe7, 0x34, 0x08, 0x9b, 0x78, 0xe8, 0x49, 0xce, 0x84, - 0xc9, 0x12, 0x2a, 0xd3, 0x47, 0xf8, 0x46, 0x44, 0x89, 0x0f, 0x05, 0x95, 0xdd, 0x61, 0x49, 0xaa, - 0xa5, 0xee, 0xee, 0xb0, 0x70, 0x37, 0x85, 0x61, 0xff, 0x4f, 0x0b, 0x1e, 0xca, 0x1c, 0x8a, 0x63, - 0xd0, 0xd3, 0x3b, 0x49, 0x3d, 0x5d, 0xcd, 0x6b, 0x13, 0x63, 0xbc, 0x45, 0x0f, 0x9d, 0xfd, 0x9f, - 0x2c, 0x18, 0xd3, 0xf8, 0xc7, 0xf0, 0xaa, 0x6e, 0xf2, 0x55, 0xf3, 0xdb, 0xaf, 0x55, 0xba, 0xde, - 0xed, 0xf7, 0x0a, 0xa0, 0xca, 0x0c, 0xcf, 0xd4, 0x64, 0x11, 0xf7, 0x7d, 0x4e, 0x8d, 0x3b, 0x30, - 0xc8, 0x0e, 0xbd, 0xa3, 0x7c, 0x02, 0x7a, 0x92, 0xfc, 0xd9, 0x01, 0xba, 0x0e, 0x28, 0x60, 0x7f, - 0x23, 0x2c, 0x18, 0xb2, 0x6b, 0x11, 0x78, 0x05, 0xd7, 0xba, 0x48, 0xc1, 0xd3, 0xd7, 0x22, 0x88, - 0x76, 0xac, 0x30, 0xa8, 0x26, 0x71, 0x6b, 0x81, 0x3f, 0xe7, 0x39, 0x91, 0xbc, 0x5e, 0x5b, 0x69, - 0x92, 0x45, 0x09, 0xc0, 0x1a, 0x87, 0x9d, 0x87, 0xbb, 0x51, 0xcb, 0x73, 0x3a, 0xc6, 0xae, 0xdc, - 0xa8, 0xb5, 0xa2, 0x40, 0xd8, 0xc4, 0xb3, 0x9b, 0x30, 0x91, 0x7c, 0x89, 0x79, 0xb2, 0xc1, 0x82, - 0x51, 0xfb, 0x1a, 0xce, 0x69, 0xa8, 0x38, 0xec, 0xa9, 0xa5, 0xb6, 0x23, 0x64, 0x82, 0x0e, 0xc9, - 0x94, 0x00, 0xac, 0x71, 0xec, 0x7f, 0x6a, 0xc1, 0xa9, 0x8c, 0x41, 0xcb, 0x31, 0xc5, 0x31, 0xd6, - 0xd2, 0x26, 0xcb, 0x06, 0xf8, 0x21, 0x18, 0xaa, 0x93, 0x0d, 0x47, 0x86, 0x3b, 0x1a, 0xd2, 0x73, - 0x9e, 0x37, 0x63, 0x09, 0xb7, 0x7f, 0xab, 0x00, 0xe3, 0xc9, 0xbe, 0x46, 0x2c, 0x6d, 0x88, 0x0f, - 0x93, 0x1b, 0xd5, 0x82, 0x6d, 0x12, 0x76, 0xe8, 0x9b, 0x5b, 0xa9, 0xb4, 0xa1, 0x2e, 0x0c, 0x9c, - 0xf1, 0x14, 0x2b, 0x32, 0x5e, 0x57, 0xa3, 0x2d, 0x67, 0xe4, 0xf5, 0x3c, 0x67, 0xa4, 0xfe, 0x98, - 0x66, 0x68, 0x84, 0x62, 0x89, 0x4d, 0xfe, 0xd4, 0x16, 0x61, 0x71, 0xd8, 0xb3, 0x6d, 0xd7, 0x8b, - 0x5d, 0x5f, 0xbc, 0xb2, 0x98, 0xab, 0xca, 0x16, 0x59, 0xee, 0x46, 0xc1, 0x59, 0xcf, 0xd9, 0xdf, - 0x19, 0x00, 0x95, 0xbe, 0xcf, 0x42, 0xd7, 0x72, 0x0a, 0xfc, 0x3b, 0x68, 0xf2, 0x99, 0x9a, 0x5b, - 0x03, 0x7b, 0xc5, 0x92, 0x70, 0x57, 0x8e, 0xe9, 0xcf, 0x55, 0x03, 0xb6, 0xa6, 0x41, 0xd8, 0xc4, - 0xa3, 0x3d, 0xf1, 0xdc, 0x6d, 0xc2, 0x1f, 0x1a, 0x4c, 0xf6, 0x64, 0x49, 0x02, 0xb0, 0xc6, 0xa1, - 0x3d, 0xa9, 0xbb, 0x1b, 0x1b, 0xc2, 0x2f, 0xa1, 0x7a, 0x42, 0x47, 0x07, 0x33, 0x08, 0xbf, 0x86, - 0x22, 0xd8, 0x12, 0xf6, 0xb7, 0x71, 0x0d, 0x45, 0xb0, 0x85, 0x19, 0x84, 0x7e, 0x25, 0x3f, 0x08, - 0x9b, 0x8e, 0xe7, 0xbe, 0x46, 0xea, 0x8a, 0x8b, 0xb0, 0xbb, 0xd5, 0x57, 0xba, 0xda, 0x8d, 0x82, - 0xb3, 0x9e, 0xa3, 0x13, 0xba, 0x15, 0x92, 0xba, 0x5b, 0x8b, 0x4d, 0x6a, 0x90, 0x9c, 0xd0, 0xab, - 0x5d, 0x18, 0x38, 0xe3, 0x29, 0x34, 0x03, 0xe3, 0xb2, 0xfc, 0x82, 0x2c, 0xe8, 0x35, 0x9c, 0x2c, - 0x20, 0x84, 0x93, 0x60, 0x9c, 0xc6, 0xa7, 0x42, 0xb2, 0x29, 0xca, 0x11, 0x32, 0x33, 0xdd, 0x10, - 0x92, 0xb2, 0x4c, 0x21, 0x56, 0x18, 0xf6, 0x87, 0x8b, 0x54, 0xa9, 0xf7, 0xa8, 0xfa, 0x79, 0x6c, - 0x81, 0xa6, 0xc9, 0x19, 0x39, 0xd0, 0xc7, 0x8c, 0x7c, 0x16, 0x46, 0x6e, 0x46, 0x81, 0xaf, 0x82, - 0x38, 0x4b, 0x3d, 0x83, 0x38, 0x0d, 0xac, 0xec, 0x20, 0xce, 0xc1, 0xbc, 0x82, 0x38, 0x87, 0xee, - 0x32, 0x88, 0xf3, 0x0f, 0x4a, 0xa0, 0xee, 0x19, 0xbb, 0x4a, 0xe2, 0x5b, 0x41, 0xb8, 0xe5, 0xfa, - 0x0d, 0x56, 0x4a, 0xe0, 0x4b, 0x96, 0xac, 0x46, 0xb0, 0x64, 0x26, 0xe1, 0x6d, 0xe4, 0x74, 0x57, - 0x54, 0x82, 0xd9, 0xd4, 0x9a, 0xc1, 0x28, 0x75, 0x1d, 0xba, 0x09, 0xc2, 0x89, 0x1e, 0xa1, 0x0f, - 0x00, 0x48, 0x27, 0xee, 0x86, 0x94, 0xc0, 0x8b, 0xf9, 0xf4, 0x0f, 0x93, 0x0d, 0x6d, 0x52, 0xaf, - 0x29, 0x26, 0xd8, 0x60, 0x88, 0x3e, 0xae, 0x13, 0x14, 0x79, 0xb6, 0xc7, 0xfb, 0x8e, 0x64, 0x6c, - 0xfa, 0x49, 0x4f, 0xc4, 0x30, 0xe4, 0xfa, 0x0d, 0x3a, 0x4f, 0x44, 0xb0, 0xdb, 0x5b, 0xb2, 0x4a, - 0xbe, 0x2c, 0x05, 0x4e, 0x7d, 0xd6, 0xf1, 0x1c, 0xbf, 0x46, 0xc2, 0x45, 0x8e, 0xae, 0x35, 0xa8, - 0x68, 0xc0, 0x92, 0x50, 0xd7, 0x65, 0x68, 0xa5, 0x7e, 0x2e, 0x43, 0x3b, 0xfb, 0x4e, 0x38, 0xd9, - 0xf5, 0x31, 0x0f, 0x94, 0x8d, 0x78, 0xf7, 0x89, 0x8c, 0xf6, 0x6f, 0x0f, 0x6a, 0xa5, 0x75, 0x35, - 0xa8, 0xf3, 0xbb, 0xb5, 0x42, 0xfd, 0x45, 0x85, 0xc9, 0x9c, 0xe3, 0x14, 0x51, 0x6a, 0xc6, 0x68, - 0xc4, 0x26, 0x4b, 0x3a, 0x47, 0x5b, 0x4e, 0x48, 0xfc, 0xa3, 0x9e, 0xa3, 0xab, 0x8a, 0x09, 0x36, - 0x18, 0xa2, 0xcd, 0x44, 0x3a, 0xd2, 0xc5, 0xc3, 0xa7, 0x23, 0xb1, 0x02, 0x7c, 0x59, 0x57, 0xd0, - 0x7c, 0xd6, 0x82, 0x31, 0x3f, 0x31, 0x73, 0xf3, 0x89, 0x40, 0xce, 0x5e, 0x15, 0xfc, 0x9a, 0xca, - 0x64, 0x1b, 0x4e, 0xf1, 0xcf, 0x52, 0x69, 0xa5, 0x03, 0xaa, 0x34, 0x7d, 0xb7, 0xdf, 0x60, 0xaf, - 0xbb, 0xfd, 0x90, 0xaf, 0x6e, 0x5c, 0x1d, 0xca, 0xfd, 0xc6, 0x55, 0xc8, 0xb8, 0x6d, 0xf5, 0x06, - 0x54, 0x6a, 0x21, 0x71, 0xe2, 0xbb, 0xbc, 0x7c, 0x93, 0xc5, 0x76, 0xcc, 0x49, 0x02, 0x58, 0xd3, - 0xb2, 0xff, 0xcf, 0x00, 0x9c, 0x90, 0x23, 0x22, 0xb3, 0x17, 0xa8, 0x7e, 0xe4, 0x7c, 0xb5, 0xad, - 0xac, 0xf4, 0xe3, 0x25, 0x09, 0xc0, 0x1a, 0x87, 0xda, 0x63, 0xed, 0x88, 0xac, 0xb4, 0x88, 0xbf, - 0xe4, 0xae, 0x47, 0xe2, 0x30, 0x56, 0x2d, 0x94, 0x6b, 0x1a, 0x84, 0x4d, 0x3c, 0x6a, 0xdb, 0x3b, - 0x86, 0xd1, 0x6a, 0xd8, 0xf6, 0xd2, 0x50, 0x95, 0x70, 0xf4, 0x4b, 0x99, 0x65, 0xc8, 0xf3, 0xc9, - 0xf9, 0xeb, 0x4a, 0xda, 0x38, 0xe0, 0xd5, 0xd1, 0xff, 0xc8, 0x82, 0x33, 0xbc, 0x55, 0x8e, 0xe4, - 0xb5, 0x56, 0xdd, 0x89, 0x49, 0x94, 0xcf, 0xf5, 0x25, 0x19, 0xfd, 0xd3, 0xee, 0xe5, 0x2c, 0xb6, - 0x38, 0xbb, 0x37, 0xe8, 0x33, 0x16, 0x8c, 0x6f, 0x25, 0xca, 0xc5, 0x48, 0xd5, 0x71, 0xd8, 0x4a, - 0x0e, 0x09, 0xa2, 0x7a, 0xa9, 0x25, 0xdb, 0x23, 0x9c, 0xe6, 0x6e, 0xff, 0x0f, 0x0b, 0x4c, 0x31, - 0x7a, 0xfc, 0x55, 0x66, 0x0e, 0x6e, 0x0a, 0x4a, 0xeb, 0xb2, 0xd4, 0xd3, 0xba, 0x7c, 0x14, 0x8a, - 0x6d, 0xb7, 0x2e, 0xf6, 0x17, 0xfa, 0x88, 0x78, 0x71, 0x1e, 0xd3, 0x76, 0xfb, 0x5f, 0x95, 0xb4, - 0x1b, 0x44, 0xa4, 0xd4, 0x7d, 0x5f, 0xbc, 0xf6, 0x86, 0xaa, 0xc3, 0xc8, 0xdf, 0xfc, 0x6a, 0x57, - 0x1d, 0xc6, 0x1f, 0x3f, 0x78, 0xc6, 0x24, 0x1f, 0xa0, 0x5e, 0x65, 0x18, 0x87, 0xf6, 0x49, 0x97, - 0xbc, 0x09, 0x65, 0xba, 0x05, 0x63, 0xfe, 0xcc, 0x72, 0xa2, 0x53, 0xe5, 0x4b, 0xa2, 0xfd, 0xce, - 0xee, 0xe4, 0x8f, 0x1d, 0xbc, 0x5b, 0xf2, 0x69, 0xac, 0xe8, 0xa3, 0x08, 0x2a, 0xf4, 0x37, 0xcb, - 0xec, 0x14, 0x9b, 0xbb, 0x6b, 0x4a, 0x66, 0x4a, 0x40, 0x2e, 0x69, 0xa3, 0x9a, 0x0f, 0xf2, 0xa1, - 0xc2, 0x6e, 0xd9, 0x67, 0x4c, 0xf9, 0x1e, 0x70, 0x55, 0xe5, 0x57, 0x4a, 0xc0, 0x9d, 0xdd, 0xc9, - 0x17, 0x0e, 0xce, 0x54, 0x3d, 0x8e, 0x35, 0x0b, 0xfb, 0x6f, 0x06, 0xf4, 0xdc, 0x15, 0xe5, 0x37, - 0xbf, 0x2f, 0xe6, 0xee, 0xf3, 0xa9, 0xb9, 0x7b, 0xae, 0x6b, 0xee, 0x8e, 0xe9, 0x2b, 0xd8, 0x13, - 0xb3, 0xf1, 0xb8, 0x0d, 0x81, 0xfd, 0xfd, 0x0d, 0xcc, 0x02, 0x7a, 0xb5, 0xed, 0x86, 0x24, 0x5a, - 0x0d, 0xdb, 0xbe, 0xeb, 0x37, 0xd8, 0x74, 0x2c, 0x9b, 0x16, 0x50, 0x02, 0x8c, 0xd3, 0xf8, 0x74, - 0x53, 0x4f, 0xbf, 0xf9, 0x0d, 0x67, 0x9b, 0xcf, 0x2a, 0xa3, 0x62, 0x5b, 0x55, 0xb4, 0x63, 0x85, - 0x81, 0x36, 0xe1, 0x11, 0x49, 0x60, 0x9e, 0x78, 0x44, 0xdc, 0xa1, 0xbe, 0xe1, 0x86, 0x4d, 0x1e, - 0x20, 0xce, 0x23, 0x13, 0xde, 0x2c, 0x28, 0x3c, 0x82, 0xf7, 0xc0, 0xc5, 0x7b, 0x52, 0xb2, 0xbf, - 0xca, 0xce, 0xeb, 0x8d, 0xe4, 0x75, 0x3a, 0xfb, 0x3c, 0xb7, 0xe9, 0xca, 0xc2, 0x72, 0x6a, 0xf6, - 0x2d, 0xd1, 0x46, 0xcc, 0x61, 0xe8, 0x16, 0x0c, 0xad, 0xf3, 0xab, 0x6e, 0xf3, 0xb9, 0x56, 0x43, - 0xdc, 0x9b, 0xcb, 0xaa, 0xb3, 0xca, 0x4b, 0x74, 0xef, 0xe8, 0x9f, 0x58, 0x72, 0xb3, 0xbf, 0x51, - 0x82, 0xf1, 0xd4, 0xbd, 0xf6, 0x89, 0x92, 0xd5, 0x85, 0x7d, 0x4b, 0x56, 0xbf, 0x17, 0xa0, 0x4e, - 0x5a, 0x5e, 0xd0, 0x61, 0x86, 0xdf, 0xc0, 0x81, 0x0d, 0x3f, 0xb5, 0x57, 0x98, 0x57, 0x54, 0xb0, - 0x41, 0x51, 0x54, 0xd3, 0xe3, 0x15, 0xb0, 0x53, 0xd5, 0xf4, 0x8c, 0xcb, 0x77, 0x06, 0x8f, 0xf7, - 0xf2, 0x1d, 0x17, 0xc6, 0x79, 0x17, 0x55, 0x8a, 0xf8, 0x5d, 0x64, 0x82, 0xb3, 0x24, 0x9b, 0xf9, - 0x24, 0x19, 0x9c, 0xa6, 0x6b, 0xde, 0xac, 0x53, 0x3e, 0xee, 0x9b, 0x75, 0xde, 0x0a, 0x15, 0xf9, - 0x9d, 0xa3, 0x89, 0x8a, 0x2e, 0xb3, 0x21, 0xa7, 0x41, 0x84, 0x35, 0xbc, 0xab, 0xda, 0x05, 0xdc, - 0xab, 0x6a, 0x17, 0xf6, 0xa7, 0x0b, 0x74, 0xc7, 0xc0, 0xfb, 0xa5, 0x0a, 0x37, 0x3d, 0x01, 0x83, - 0x4e, 0x3b, 0xde, 0x0c, 0xba, 0x2e, 0xcb, 0x9d, 0x61, 0xad, 0x58, 0x40, 0xd1, 0x12, 0x0c, 0xd4, - 0x75, 0x31, 0x9e, 0x83, 0x7c, 0x4f, 0xed, 0x7c, 0x75, 0x62, 0x82, 0x19, 0x15, 0xf4, 0x08, 0x0c, - 0xc4, 0x4e, 0x43, 0xe6, 0x05, 0xb2, 0x5c, 0xf0, 0x35, 0xa7, 0x11, 0x61, 0xd6, 0x7a, 0x90, 0x02, - 0xa4, 0x2f, 0xc0, 0x68, 0xe4, 0x36, 0x7c, 0x27, 0x6e, 0x87, 0xc4, 0x38, 0x9f, 0xd4, 0xd1, 0x29, - 0x26, 0x10, 0x27, 0x71, 0xed, 0xdf, 0x19, 0x81, 0xd3, 0xd5, 0xb9, 0x65, 0x79, 0x85, 0xc2, 0x91, - 0xa5, 0xf6, 0x65, 0xf1, 0x38, 0xbe, 0xd4, 0xbe, 0x1e, 0xdc, 0x3d, 0x23, 0xb5, 0xcf, 0x33, 0x52, - 0xfb, 0x92, 0x79, 0x56, 0xc5, 0x3c, 0xf2, 0xac, 0xb2, 0x7a, 0xd0, 0x4f, 0x9e, 0xd5, 0x91, 0xe5, - 0xfa, 0xed, 0xd9, 0xa1, 0x03, 0xe5, 0xfa, 0xa9, 0x44, 0xc8, 0x5c, 0x32, 0x60, 0x7a, 0x7c, 0xaa, - 0xcc, 0x44, 0x48, 0x95, 0x84, 0xc6, 0xb3, 0xbb, 0x84, 0xa8, 0x7f, 0x39, 0xff, 0x0e, 0xf4, 0x91, - 0x84, 0x26, 0x12, 0xcc, 0xcc, 0xc4, 0xc7, 0xa1, 0x3c, 0x12, 0x1f, 0xb3, 0xba, 0xb3, 0x6f, 0xe2, - 0xe3, 0x0b, 0x30, 0x5a, 0xf3, 0x02, 0x9f, 0xac, 0x86, 0x41, 0x1c, 0xd4, 0x02, 0x79, 0x5d, 0xa7, - 0xbe, 0x6d, 0xca, 0x04, 0xe2, 0x24, 0x6e, 0xaf, 0xac, 0xc9, 0xca, 0x61, 0xb3, 0x26, 0xe1, 0x1e, - 0x65, 0x4d, 0xfe, 0xac, 0xce, 0xef, 0x1f, 0x66, 0x5f, 0xe4, 0xbd, 0xf9, 0x7f, 0x91, 0xbe, 0xee, - 0xe3, 0x7c, 0x9d, 0xdf, 0x56, 0x4b, 0x4d, 0xf0, 0xb9, 0xa0, 0x49, 0x0d, 0xbf, 0x11, 0x36, 0x24, - 0xaf, 0x1c, 0xc1, 0x84, 0xbd, 0x51, 0xd5, 0x6c, 0xd4, 0x0d, 0xb6, 0xba, 0x09, 0x27, 0x3b, 0x72, - 0x98, 0xfa, 0x03, 0x5f, 0x28, 0xc0, 0x0f, 0xec, 0xdb, 0x05, 0x74, 0x0b, 0x20, 0x76, 0x1a, 0x62, - 0xa2, 0x8a, 0xa3, 0x99, 0x43, 0x86, 0x90, 0xae, 0x49, 0x7a, 0xbc, 0x70, 0x8e, 0xfa, 0xcb, 0x0e, - 0x3d, 0xe4, 0x6f, 0x16, 0x39, 0x1a, 0x78, 0x5d, 0xf5, 0x45, 0x71, 0xe0, 0x11, 0xcc, 0x20, 0x54, - 0xfd, 0x87, 0xa4, 0x41, 0x4d, 0xda, 0x62, 0x52, 0xfd, 0x63, 0xd6, 0x8a, 0x05, 0x14, 0x3d, 0x07, - 0xc3, 0x8e, 0xe7, 0xf1, 0xf4, 0x24, 0x12, 0x89, 0x6b, 0xe0, 0x74, 0xa1, 0x43, 0x0d, 0xc2, 0x26, - 0x9e, 0xfd, 0x57, 0x05, 0x98, 0xdc, 0x47, 0xa6, 0x74, 0xa5, 0xa5, 0x96, 0xfa, 0x4e, 0x4b, 0x15, - 0x29, 0x1b, 0x83, 0x3d, 0x52, 0x36, 0x9e, 0x83, 0xe1, 0x98, 0x38, 0x4d, 0x11, 0x74, 0x26, 0x7c, - 0x0e, 0xfa, 0xac, 0x59, 0x83, 0xb0, 0x89, 0x47, 0xa5, 0xd8, 0x98, 0x53, 0xab, 0x91, 0x28, 0x92, - 0x39, 0x19, 0xc2, 0x6f, 0x9b, 0x5b, 0xc2, 0x07, 0x73, 0x87, 0xcf, 0x24, 0x58, 0xe0, 0x14, 0xcb, - 0xf4, 0x80, 0x57, 0xfa, 0x1c, 0xf0, 0x2f, 0x17, 0xe0, 0xd1, 0x3d, 0xb5, 0x5b, 0xdf, 0xe9, 0x32, - 0xed, 0x88, 0x84, 0xe9, 0x89, 0x73, 0x2d, 0x22, 0x21, 0x66, 0x10, 0x3e, 0x4a, 0xad, 0x96, 0x0a, - 0x18, 0xce, 0x3f, 0x77, 0x8c, 0x8f, 0x52, 0x82, 0x05, 0x4e, 0xb1, 0xbc, 0xdb, 0x69, 0xf9, 0x8d, - 0x01, 0x78, 0xbc, 0x0f, 0x1b, 0x20, 0xc7, 0x1c, 0xbb, 0x64, 0x3e, 0x68, 0xf1, 0x1e, 0xe5, 0x83, - 0xde, 0xdd, 0x70, 0xbd, 0x91, 0x46, 0xda, 0x57, 0x2e, 0xdf, 0x57, 0x0b, 0x70, 0xb6, 0xb7, 0xc1, - 0x82, 0xde, 0x0e, 0xe3, 0xa1, 0x0a, 0xb2, 0x33, 0x53, 0x49, 0x4f, 0x71, 0xcf, 0x4e, 0x02, 0x84, - 0xd3, 0xb8, 0x68, 0x0a, 0xa0, 0xe5, 0xc4, 0x9b, 0xd1, 0x85, 0x1d, 0x37, 0x8a, 0x45, 0x41, 0xa9, - 0x31, 0x7e, 0x96, 0x28, 0x5b, 0xb1, 0x81, 0x41, 0xd9, 0xb1, 0x7f, 0xf3, 0xc1, 0xd5, 0x20, 0xe6, - 0x0f, 0xf1, 0xcd, 0xd6, 0x29, 0x79, 0xbd, 0x94, 0x01, 0xc2, 0x69, 0x5c, 0xca, 0x8e, 0x9d, 0x56, - 0xf3, 0x8e, 0xf2, 0x5d, 0x18, 0x63, 0xb7, 0xa4, 0x5a, 0xb1, 0x81, 0x91, 0x4e, 0x92, 0x2d, 0xed, - 0x9f, 0x24, 0x6b, 0xff, 0xcb, 0x02, 0x3c, 0xd4, 0xd3, 0xe0, 0xed, 0x4f, 0x4c, 0xdd, 0x7f, 0x89, - 0xad, 0x77, 0xb9, 0xc2, 0x0e, 0x96, 0x10, 0xf9, 0xa7, 0x3d, 0x66, 0x9a, 0x48, 0x88, 0xbc, 0xfb, - 0x3a, 0x0f, 0xf7, 0xdf, 0x78, 0x76, 0xe5, 0x40, 0x0e, 0x1c, 0x20, 0x07, 0x32, 0xf5, 0x31, 0x4a, - 0x7d, 0x6a, 0x87, 0x3f, 0x1f, 0xe8, 0x39, 0xbc, 0x74, 0x83, 0xdc, 0x97, 0xdf, 0x7c, 0x1e, 0x4e, - 0xb8, 0x3e, 0xbb, 0x6a, 0xb0, 0xda, 0x5e, 0x17, 0x35, 0x86, 0x78, 0x21, 0x4d, 0x95, 0x68, 0xb1, - 0x98, 0x82, 0xe3, 0xae, 0x27, 0xee, 0xc3, 0x9c, 0xd4, 0xbb, 0x1b, 0xd2, 0x03, 0x4a, 0xee, 0x15, - 0x38, 0x23, 0x87, 0x62, 0xd3, 0x09, 0x49, 0x5d, 0x28, 0xdb, 0x48, 0xa4, 0xd6, 0x3c, 0xc4, 0xd3, - 0x73, 0x32, 0x10, 0x70, 0xf6, 0x73, 0xec, 0x76, 0xb7, 0xa0, 0xe5, 0xd6, 0xc4, 0x56, 0x50, 0xdf, - 0xee, 0x46, 0x1b, 0x31, 0x87, 0x69, 0x7d, 0x51, 0x39, 0x1e, 0x7d, 0xf1, 0x5e, 0xa8, 0xa8, 0xf1, - 0xe6, 0x59, 0x02, 0x6a, 0x92, 0x77, 0x65, 0x09, 0xa8, 0x19, 0x6e, 0x60, 0xed, 0x77, 0x33, 0xf2, - 0x8f, 0xc0, 0x88, 0xf2, 0x7e, 0xf5, 0x7b, 0xc7, 0x9e, 0xfd, 0x7f, 0x0b, 0x90, 0xba, 0x05, 0x07, - 0xed, 0x40, 0xa5, 0x2e, 0xef, 0x26, 0xce, 0xa7, 0x90, 0xab, 0xba, 0xea, 0x58, 0x1f, 0xff, 0xa8, - 0x26, 0xac, 0x99, 0xa1, 0xf7, 0xf3, 0x9a, 0xa9, 0x82, 0x75, 0x21, 0x8f, 0xbc, 0xe4, 0xaa, 0xa2, - 0x67, 0x5e, 0xa2, 0x25, 0xdb, 0xb0, 0xc1, 0x0f, 0xc5, 0x50, 0xd9, 0x94, 0xb7, 0xfd, 0xe4, 0x23, - 0xee, 0xd4, 0xe5, 0x41, 0xdc, 0x44, 0x53, 0x7f, 0xb1, 0x66, 0x64, 0xff, 0x49, 0x01, 0x4e, 0x27, - 0x3f, 0x80, 0x38, 0xae, 0xfb, 0x35, 0x0b, 0x1e, 0xf4, 0x9c, 0x28, 0xae, 0xb6, 0xd9, 0x46, 0x61, - 0xa3, 0xed, 0xad, 0xa4, 0xca, 0xeb, 0x1e, 0xd6, 0xd9, 0xa2, 0x08, 0xa7, 0x6f, 0x87, 0x9a, 0x7d, - 0xf8, 0xf6, 0xee, 0xe4, 0x83, 0x4b, 0xd9, 0xcc, 0x71, 0xaf, 0x5e, 0xa1, 0xcf, 0x5a, 0x70, 0xa2, - 0xd6, 0x0e, 0x43, 0xe2, 0xc7, 0xba, 0xab, 0xfc, 0x2b, 0x5e, 0xcd, 0x65, 0x20, 0x75, 0x07, 0x4f, - 0x53, 0x81, 0x3a, 0x97, 0xe2, 0x85, 0xbb, 0xb8, 0xdb, 0xbf, 0x40, 0x35, 0x67, 0xcf, 0xf7, 0xfc, - 0x5b, 0x76, 0x9d, 0xd5, 0x5f, 0x0c, 0xc2, 0x68, 0xa2, 0x86, 0x70, 0xe2, 0x88, 0xcb, 0xda, 0xf7, - 0x88, 0x8b, 0x25, 0x83, 0xb5, 0x7d, 0x79, 0xd9, 0xae, 0x91, 0x0c, 0xd6, 0xf6, 0x09, 0xe6, 0x30, - 0x31, 0xa4, 0xb8, 0xed, 0x8b, 0xe8, 0x76, 0x73, 0x48, 0x71, 0xdb, 0xc7, 0x02, 0x8a, 0x3e, 0x64, - 0xc1, 0x08, 0x5b, 0x7c, 0xe2, 0x80, 0x50, 0x28, 0xb4, 0xcb, 0x39, 0x2c, 0x77, 0x59, 0x2f, 0x9b, - 0x45, 0x43, 0x9a, 0x2d, 0x38, 0xc1, 0x11, 0x7d, 0xd4, 0x82, 0x8a, 0xba, 0x9f, 0x4f, 0xdc, 0x9c, - 0x5d, 0xcd, 0xb7, 0x44, 0x73, 0x4a, 0xea, 0xa9, 0x5a, 0xb9, 0x58, 0x33, 0x46, 0x91, 0x3a, 0xbd, - 0x1b, 0x3a, 0x9a, 0xd3, 0x3b, 0xc8, 0x38, 0xb9, 0x7b, 0x2b, 0x54, 0x9a, 0x8e, 0xef, 0x6e, 0x90, - 0x28, 0xe6, 0x07, 0x6a, 0xb2, 0x72, 0xbc, 0x6c, 0xc4, 0x1a, 0x4e, 0x8d, 0xfd, 0x88, 0xbd, 0x58, - 0x6c, 0x9c, 0x80, 0x31, 0x63, 0xbf, 0xaa, 0x9b, 0xb1, 0x89, 0x63, 0x1e, 0xd7, 0xc1, 0x3d, 0x3d, - 0xae, 0x1b, 0xde, 0xe7, 0xb8, 0xae, 0x0a, 0x67, 0x9c, 0x76, 0x1c, 0x5c, 0x22, 0x8e, 0x37, 0xc3, - 0x6f, 0xe8, 0x8f, 0x78, 0xd9, 0xe9, 0x11, 0xe6, 0x02, 0x56, 0xf1, 0x5b, 0x55, 0xe2, 0x6d, 0x74, - 0x21, 0xe1, 0xec, 0x67, 0xed, 0x7f, 0x6e, 0xc1, 0x99, 0xcc, 0xa9, 0x70, 0xff, 0x46, 0xce, 0xdb, - 0x9f, 0x2f, 0xc1, 0xa9, 0x8c, 0x0a, 0xe3, 0xa8, 0x63, 0x2e, 0x12, 0x2b, 0x8f, 0x20, 0xb4, 0x64, - 0x4c, 0x95, 0xfc, 0x36, 0x19, 0x2b, 0xe3, 0x60, 0x27, 0xf0, 0xfa, 0x14, 0xbc, 0x78, 0xbc, 0xa7, - 0xe0, 0xc6, 0x5c, 0x1f, 0xb8, 0xa7, 0x73, 0xbd, 0xb4, 0xcf, 0x5c, 0xff, 0x9a, 0x05, 0x13, 0xcd, - 0x1e, 0xd7, 0xda, 0x88, 0xf3, 0xa4, 0xeb, 0x47, 0x73, 0x69, 0xce, 0xec, 0x23, 0xb7, 0x77, 0x27, - 0x7b, 0xde, 0x26, 0x84, 0x7b, 0xf6, 0xca, 0xfe, 0x4e, 0x11, 0x98, 0xbd, 0xc6, 0xaa, 0xc8, 0x76, - 0xd0, 0x07, 0xcd, 0x8b, 0x0a, 0xac, 0xbc, 0x8a, 0xea, 0x73, 0xe2, 0xea, 0xa2, 0x03, 0x3e, 0x82, - 0x59, 0xf7, 0x1e, 0xa4, 0x25, 0x61, 0xa1, 0x0f, 0x49, 0xe8, 0xc9, 0x1b, 0x21, 0x8a, 0xf9, 0xdf, - 0x08, 0x51, 0x49, 0xdf, 0x06, 0xb1, 0xf7, 0x27, 0x1e, 0xb8, 0x2f, 0x3f, 0xf1, 0x2f, 0x5b, 0x5c, - 0xf0, 0xa4, 0xbe, 0x82, 0x36, 0x37, 0xac, 0x3d, 0xcc, 0x8d, 0xa7, 0xa0, 0x1c, 0x09, 0xc9, 0x2c, - 0xcc, 0x12, 0x1d, 0x00, 0x25, 0xda, 0xb1, 0xc2, 0xa0, 0xbb, 0x2e, 0xc7, 0xf3, 0x82, 0x5b, 0x17, - 0x9a, 0xad, 0xb8, 0x23, 0x0c, 0x14, 0xb5, 0x2d, 0x98, 0x51, 0x10, 0x6c, 0x60, 0xd9, 0x9b, 0x60, - 0x6c, 0x18, 0xee, 0xfe, 0x16, 0xd0, 0x3e, 0xae, 0x6f, 0xfe, 0x87, 0x05, 0xc1, 0x8a, 0x6f, 0x00, - 0x9e, 0x4f, 0x5d, 0x97, 0xdd, 0x7f, 0xa8, 0xdb, 0xfb, 0x01, 0x6a, 0x41, 0xb3, 0x45, 0xb7, 0xc4, - 0x6b, 0x41, 0x3e, 0xfb, 0xa8, 0x39, 0x45, 0x4f, 0x0f, 0x98, 0x6e, 0xc3, 0x06, 0xbf, 0x84, 0xd4, - 0x2e, 0xee, 0x2b, 0xb5, 0x13, 0x02, 0x6c, 0x60, 0x6f, 0x01, 0x66, 0xff, 0x95, 0x05, 0x09, 0x83, - 0x0e, 0xb5, 0xa0, 0x44, 0xbb, 0xdb, 0x11, 0xb2, 0x60, 0x25, 0x3f, 0xeb, 0x91, 0x0a, 0x61, 0xb1, - 0xc0, 0xd8, 0x4f, 0xcc, 0x19, 0x21, 0x4f, 0x84, 0xf5, 0xe5, 0xb2, 0xaf, 0x31, 0x19, 0x5e, 0x0a, - 0x82, 0x2d, 0x1e, 0x19, 0xa3, 0x43, 0x04, 0xed, 0xe7, 0xe1, 0x64, 0x57, 0xa7, 0xd8, 0xcd, 0xa1, - 0x81, 0xdc, 0x9c, 0x1b, 0x0b, 0x83, 0x55, 0x39, 0xc0, 0x1c, 0x66, 0x7f, 0xd5, 0x82, 0x13, 0x69, - 0xf2, 0xe8, 0x75, 0x0b, 0x4e, 0x46, 0x69, 0x7a, 0x47, 0x35, 0x76, 0x2a, 0x34, 0xbf, 0x0b, 0x84, - 0xbb, 0x3b, 0x61, 0xff, 0x8d, 0x98, 0xfc, 0x37, 0x5c, 0xbf, 0x1e, 0xdc, 0x52, 0x26, 0x90, 0xd5, - 0xd3, 0x04, 0xa2, 0x2b, 0xbf, 0xb6, 0x49, 0xea, 0x6d, 0xaf, 0xab, 0x66, 0x42, 0x55, 0xb4, 0x63, - 0x85, 0xc1, 0x52, 0xc4, 0xdb, 0x62, 0x4b, 0x9a, 0x9a, 0x94, 0xf3, 0xa2, 0x1d, 0x2b, 0x0c, 0xf4, - 0x2c, 0x8c, 0x18, 0x2f, 0x29, 0xe7, 0x25, 0xdb, 0x4f, 0x18, 0xca, 0x39, 0xc2, 0x09, 0x2c, 0x34, - 0x05, 0xa0, 0xcc, 0x29, 0xa9, 0x8c, 0x99, 0x0f, 0x5d, 0xc9, 0xbc, 0x08, 0x1b, 0x18, 0xac, 0x20, - 0x83, 0xd7, 0x8e, 0xd8, 0x21, 0xf1, 0xa0, 0x2e, 0x98, 0x3e, 0x27, 0xda, 0xb0, 0x82, 0x52, 0xb9, - 0xd5, 0x74, 0xfc, 0xb6, 0xe3, 0xd1, 0x11, 0x12, 0x5e, 0x31, 0xb5, 0x0c, 0x97, 0x15, 0x04, 0x1b, - 0x58, 0xf4, 0x8d, 0x63, 0xb7, 0x49, 0x5e, 0x0a, 0x7c, 0x19, 0x52, 0xad, 0xe3, 0x06, 0x44, 0x3b, - 0x56, 0x18, 0xf6, 0x5f, 0x5a, 0x30, 0xae, 0x2b, 0xc1, 0x30, 0x5f, 0x56, 0xc2, 0x89, 0x67, 0xed, - 0xeb, 0xc4, 0x4b, 0xd6, 0xbd, 0x28, 0xf4, 0x55, 0xf7, 0xc2, 0x2c, 0x49, 0x51, 0xdc, 0xb3, 0x24, - 0xc5, 0x0f, 0xc2, 0xd0, 0x16, 0xe9, 0x18, 0xb5, 0x2b, 0x86, 0xa9, 0x39, 0x74, 0x85, 0x37, 0x61, - 0x09, 0x43, 0x36, 0x0c, 0xd6, 0x1c, 0x55, 0x31, 0x6d, 0x84, 0x6f, 0x7d, 0xe6, 0x66, 0x18, 0x92, - 0x80, 0xd8, 0x2b, 0x50, 0x51, 0xc7, 0xe7, 0xd2, 0xa7, 0x66, 0x65, 0xfb, 0xd4, 0xfa, 0x4a, 0x8d, - 0x9f, 0x5d, 0xff, 0xfa, 0x77, 0x1f, 0x7b, 0xd3, 0x1f, 0x7d, 0xf7, 0xb1, 0x37, 0x7d, 0xfb, 0xbb, - 0x8f, 0xbd, 0xe9, 0x43, 0xb7, 0x1f, 0xb3, 0xbe, 0x7e, 0xfb, 0x31, 0xeb, 0x8f, 0x6e, 0x3f, 0x66, - 0x7d, 0xfb, 0xf6, 0x63, 0xd6, 0x77, 0x6e, 0x3f, 0x66, 0x7d, 0xf6, 0xbf, 0x3e, 0xf6, 0xa6, 0x97, - 0x32, 0x63, 0xea, 0xe9, 0x8f, 0xa7, 0x6b, 0xf5, 0xe9, 0xed, 0xf3, 0x2c, 0xac, 0x9b, 0x2e, 0xaf, - 0x69, 0x63, 0x4e, 0x4d, 0xcb, 0xe5, 0xf5, 0xff, 0x02, 0x00, 0x00, 0xff, 0xff, 0xa6, 0xfc, 0x44, - 0xf5, 0xc0, 0xf5, 0x00, 0x00, + // 11913 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x7d, 0x6d, 0x70, 0x1c, 0xc9, + 0x75, 0x98, 0x66, 0x17, 0x0b, 0xec, 0x3e, 0x7c, 0x91, 0x4d, 0xf2, 0x0e, 0xc7, 0xfb, 0x00, 0x3d, + 0x27, 0x9f, 0xce, 0xd1, 0x1d, 0xe0, 0xa3, 0xef, 0xe4, 0x8b, 0xcf, 0x96, 0x8c, 0x0f, 0x12, 0x04, + 0x09, 0x10, 0xb8, 0x5e, 0x90, 0x94, 0x4e, 0x3e, 0x9d, 0x06, 0xbb, 0x8d, 0xc5, 0x10, 0xb3, 0x33, + 0x7b, 0x33, 0xb3, 0x20, 0xf6, 0x2c, 0xc9, 0x92, 0x25, 0xd9, 0xb2, 0xf5, 0x19, 0x29, 0x15, 0x9f, + 0x13, 0x4b, 0x91, 0x2d, 0x25, 0x95, 0x54, 0x4a, 0x65, 0x25, 0xfe, 0x11, 0x27, 0x76, 0xca, 0x15, + 0x3b, 0xe5, 0x52, 0xe2, 0xb8, 0xec, 0xa8, 0x54, 0x96, 0x12, 0xdb, 0x88, 0xc4, 0x38, 0x65, 0x57, + 0x7e, 0xb8, 0x2a, 0x4e, 0x7e, 0xa4, 0x18, 0x57, 0x2a, 0xd5, 0xdf, 0x3d, 0xb3, 0xb3, 0xc0, 0x82, + 0x18, 0x80, 0x94, 0x7c, 0xff, 0x76, 0xfb, 0xbd, 0x79, 0xaf, 0xa7, 0xa7, 0xfb, 0xbd, 0xd7, 0xaf, + 0xdf, 0x7b, 0x0d, 0x4b, 0x0d, 0x37, 0xde, 0x6c, 0xaf, 0x4f, 0xd5, 0x82, 0xe6, 0xb4, 0x13, 0x36, + 0x82, 0x56, 0x18, 0xdc, 0x64, 0x3f, 0x9e, 0xae, 0xd5, 0xa7, 0xb7, 0xcf, 0x4f, 0xb7, 0xb6, 0x1a, + 0xd3, 0x4e, 0xcb, 0x8d, 0xa6, 0x9d, 0x56, 0xcb, 0x73, 0x6b, 0x4e, 0xec, 0x06, 0xfe, 0xf4, 0xf6, + 0x33, 0x8e, 0xd7, 0xda, 0x74, 0x9e, 0x99, 0x6e, 0x10, 0x9f, 0x84, 0x4e, 0x4c, 0xea, 0x53, 0xad, + 0x30, 0x88, 0x03, 0xf4, 0xa3, 0x9a, 0xda, 0x94, 0xa4, 0xc6, 0x7e, 0xbc, 0x52, 0xab, 0x4f, 0x6d, + 0x9f, 0x9f, 0x6a, 0x6d, 0x35, 0xa6, 0x28, 0xb5, 0x29, 0x83, 0xda, 0x94, 0xa4, 0x76, 0xf6, 0x69, + 0xa3, 0x2f, 0x8d, 0xa0, 0x11, 0x4c, 0x33, 0xa2, 0xeb, 0xed, 0x0d, 0xf6, 0x8f, 0xfd, 0x61, 0xbf, + 0x38, 0xb3, 0xb3, 0xf6, 0xd6, 0xf3, 0xd1, 0x94, 0x1b, 0xd0, 0xee, 0x4d, 0xd7, 0x82, 0x90, 0x4c, + 0x6f, 0x77, 0x75, 0xe8, 0xec, 0x25, 0x8d, 0x43, 0x76, 0x62, 0xe2, 0x47, 0x6e, 0xe0, 0x47, 0x4f, + 0xd3, 0x2e, 0x90, 0x70, 0x9b, 0x84, 0xe6, 0xeb, 0x19, 0x08, 0x59, 0x94, 0x9e, 0xd5, 0x94, 0x9a, + 0x4e, 0x6d, 0xd3, 0xf5, 0x49, 0xd8, 0xd1, 0x8f, 0x37, 0x49, 0xec, 0x64, 0x3d, 0x35, 0xdd, 0xeb, + 0xa9, 0xb0, 0xed, 0xc7, 0x6e, 0x93, 0x74, 0x3d, 0xf0, 0xb6, 0xfd, 0x1e, 0x88, 0x6a, 0x9b, 0xa4, + 0xe9, 0x74, 0x3d, 0xf7, 0x43, 0xbd, 0x9e, 0x6b, 0xc7, 0xae, 0x37, 0xed, 0xfa, 0x71, 0x14, 0x87, + 0xe9, 0x87, 0xec, 0x5f, 0xb2, 0x60, 0x74, 0xe6, 0x46, 0x75, 0xa6, 0x1d, 0x6f, 0xce, 0x05, 0xfe, + 0x86, 0xdb, 0x40, 0xcf, 0xc1, 0x70, 0xcd, 0x6b, 0x47, 0x31, 0x09, 0xaf, 0x3a, 0x4d, 0x32, 0x61, + 0x9d, 0xb3, 0x9e, 0xac, 0xcc, 0x9e, 0xfa, 0xda, 0xee, 0xe4, 0x9b, 0x6e, 0xef, 0x4e, 0x0e, 0xcf, + 0x69, 0x10, 0x36, 0xf1, 0xd0, 0x0f, 0xc0, 0x50, 0x18, 0x78, 0x64, 0x06, 0x5f, 0x9d, 0x28, 0xb0, + 0x47, 0xc6, 0xc5, 0x23, 0x43, 0x98, 0x37, 0x63, 0x09, 0xa7, 0xa8, 0xad, 0x30, 0xd8, 0x70, 0x3d, + 0x32, 0x51, 0x4c, 0xa2, 0xae, 0xf2, 0x66, 0x2c, 0xe1, 0xf6, 0x1f, 0x15, 0x00, 0x66, 0x5a, 0xad, + 0xd5, 0x30, 0xb8, 0x49, 0x6a, 0x31, 0x7a, 0x2f, 0x94, 0xe9, 0x30, 0xd7, 0x9d, 0xd8, 0x61, 0x1d, + 0x1b, 0x3e, 0xff, 0x83, 0x53, 0xfc, 0xad, 0xa7, 0xcc, 0xb7, 0xd6, 0x93, 0x8c, 0x62, 0x4f, 0x6d, + 0x3f, 0x33, 0xb5, 0xb2, 0x4e, 0x9f, 0x5f, 0x26, 0xb1, 0x33, 0x8b, 0x04, 0x33, 0xd0, 0x6d, 0x58, + 0x51, 0x45, 0x3e, 0x0c, 0x44, 0x2d, 0x52, 0x63, 0xef, 0x30, 0x7c, 0x7e, 0x69, 0xea, 0x30, 0xb3, + 0x79, 0x4a, 0xf7, 0xbc, 0xda, 0x22, 0xb5, 0xd9, 0x11, 0xc1, 0x79, 0x80, 0xfe, 0xc3, 0x8c, 0x0f, + 0xda, 0x86, 0xc1, 0x28, 0x76, 0xe2, 0x76, 0xc4, 0x86, 0x62, 0xf8, 0xfc, 0xd5, 0xdc, 0x38, 0x32, + 0xaa, 0xb3, 0x63, 0x82, 0xe7, 0x20, 0xff, 0x8f, 0x05, 0x37, 0xfb, 0x4f, 0x2d, 0x18, 0xd3, 0xc8, + 0x4b, 0x6e, 0x14, 0xa3, 0x9f, 0xe8, 0x1a, 0xdc, 0xa9, 0xfe, 0x06, 0x97, 0x3e, 0xcd, 0x86, 0xf6, + 0x84, 0x60, 0x56, 0x96, 0x2d, 0xc6, 0xc0, 0x36, 0xa1, 0xe4, 0xc6, 0xa4, 0x19, 0x4d, 0x14, 0xce, + 0x15, 0x9f, 0x1c, 0x3e, 0x7f, 0x29, 0xaf, 0xf7, 0x9c, 0x1d, 0x15, 0x4c, 0x4b, 0x8b, 0x94, 0x3c, + 0xe6, 0x5c, 0xec, 0xbf, 0x1a, 0x35, 0xdf, 0x8f, 0x0e, 0x38, 0x7a, 0x06, 0x86, 0xa3, 0xa0, 0x1d, + 0xd6, 0x08, 0x26, 0xad, 0x20, 0x9a, 0xb0, 0xce, 0x15, 0xe9, 0xd4, 0xa3, 0x93, 0xba, 0xaa, 0x9b, + 0xb1, 0x89, 0x83, 0x3e, 0x65, 0xc1, 0x48, 0x9d, 0x44, 0xb1, 0xeb, 0x33, 0xfe, 0xb2, 0xf3, 0x6b, + 0x87, 0xee, 0xbc, 0x6c, 0x9c, 0xd7, 0xc4, 0x67, 0x4f, 0x8b, 0x17, 0x19, 0x31, 0x1a, 0x23, 0x9c, + 0xe0, 0x4f, 0x17, 0x67, 0x9d, 0x44, 0xb5, 0xd0, 0x6d, 0xd1, 0xff, 0x62, 0xf9, 0xa8, 0xc5, 0x39, + 0xaf, 0x41, 0xd8, 0xc4, 0x43, 0x3e, 0x94, 0xe8, 0xe2, 0x8b, 0x26, 0x06, 0x58, 0xff, 0x17, 0x0f, + 0xd7, 0x7f, 0x31, 0xa8, 0x74, 0x5d, 0xeb, 0xd1, 0xa7, 0xff, 0x22, 0xcc, 0xd9, 0xa0, 0x4f, 0x5a, + 0x30, 0x21, 0x84, 0x03, 0x26, 0x7c, 0x40, 0x6f, 0x6c, 0xba, 0x31, 0xf1, 0xdc, 0x28, 0x9e, 0x28, + 0xb1, 0x3e, 0x4c, 0xf7, 0x37, 0xb7, 0x16, 0xc2, 0xa0, 0xdd, 0xba, 0xe2, 0xfa, 0xf5, 0xd9, 0x73, + 0x82, 0xd3, 0xc4, 0x5c, 0x0f, 0xc2, 0xb8, 0x27, 0x4b, 0xf4, 0x39, 0x0b, 0xce, 0xfa, 0x4e, 0x93, + 0x44, 0x2d, 0x87, 0x7e, 0x5a, 0x0e, 0x9e, 0xf5, 0x9c, 0xda, 0x16, 0xeb, 0xd1, 0xe0, 0xdd, 0xf5, + 0xc8, 0x16, 0x3d, 0x3a, 0x7b, 0xb5, 0x27, 0x69, 0xbc, 0x07, 0x5b, 0xf4, 0x25, 0x0b, 0x4e, 0x06, + 0x61, 0x6b, 0xd3, 0xf1, 0x49, 0x5d, 0x42, 0xa3, 0x89, 0x21, 0xb6, 0xf4, 0xde, 0x73, 0xb8, 0x4f, + 0xb4, 0x92, 0x26, 0xbb, 0x1c, 0xf8, 0x6e, 0x1c, 0x84, 0x55, 0x12, 0xc7, 0xae, 0xdf, 0x88, 0x66, + 0xcf, 0xdc, 0xde, 0x9d, 0x3c, 0xd9, 0x85, 0x85, 0xbb, 0xfb, 0x83, 0x7e, 0x12, 0x86, 0xa3, 0x8e, + 0x5f, 0xbb, 0xe1, 0xfa, 0xf5, 0xe0, 0x56, 0x34, 0x51, 0xce, 0x63, 0xf9, 0x56, 0x15, 0x41, 0xb1, + 0x00, 0x35, 0x03, 0x6c, 0x72, 0xcb, 0xfe, 0x70, 0x7a, 0x2a, 0x55, 0xf2, 0xfe, 0x70, 0x7a, 0x32, + 0xed, 0xc1, 0x16, 0xfd, 0xac, 0x05, 0xa3, 0x91, 0xdb, 0xf0, 0x9d, 0xb8, 0x1d, 0x92, 0x2b, 0xa4, + 0x13, 0x4d, 0x00, 0xeb, 0xc8, 0xe5, 0x43, 0x8e, 0x8a, 0x41, 0x72, 0xf6, 0x8c, 0xe8, 0xe3, 0xa8, + 0xd9, 0x1a, 0xe1, 0x24, 0xdf, 0xac, 0x85, 0xa6, 0xa7, 0xf5, 0x70, 0xbe, 0x0b, 0x4d, 0x4f, 0xea, + 0x9e, 0x2c, 0xd1, 0x8f, 0xc3, 0x09, 0xde, 0xa4, 0x46, 0x36, 0x9a, 0x18, 0x61, 0x82, 0xf6, 0xf4, + 0xed, 0xdd, 0xc9, 0x13, 0xd5, 0x14, 0x0c, 0x77, 0x61, 0xa3, 0x57, 0x61, 0xb2, 0x45, 0xc2, 0xa6, + 0x1b, 0xaf, 0xf8, 0x5e, 0x47, 0x8a, 0xef, 0x5a, 0xd0, 0x22, 0x75, 0xd1, 0x9d, 0x68, 0x62, 0xf4, + 0x9c, 0xf5, 0x64, 0x79, 0xf6, 0x2d, 0xa2, 0x9b, 0x93, 0xab, 0x7b, 0xa3, 0xe3, 0xfd, 0xe8, 0xa1, + 0xdf, 0xb5, 0xe0, 0xac, 0x21, 0x65, 0xab, 0x24, 0xdc, 0x76, 0x6b, 0x64, 0xa6, 0x56, 0x0b, 0xda, + 0x7e, 0x1c, 0x4d, 0x8c, 0xb1, 0x61, 0x5c, 0x3f, 0x0a, 0x99, 0x9f, 0x64, 0xa5, 0xe7, 0x65, 0x4f, + 0x94, 0x08, 0xef, 0xd1, 0x53, 0xfb, 0xdf, 0x17, 0xe0, 0x44, 0xda, 0x02, 0x40, 0xff, 0xd8, 0x82, + 0xf1, 0x9b, 0xb7, 0xe2, 0xb5, 0x60, 0x8b, 0xf8, 0xd1, 0x6c, 0x87, 0xca, 0x69, 0xa6, 0xfb, 0x86, + 0xcf, 0xd7, 0xf2, 0xb5, 0x35, 0xa6, 0x2e, 0x27, 0xb9, 0x5c, 0xf0, 0xe3, 0xb0, 0x33, 0xfb, 0xa0, + 0x78, 0xa7, 0xf1, 0xcb, 0x37, 0xd6, 0x4c, 0x28, 0x4e, 0x77, 0xea, 0xec, 0xc7, 0x2d, 0x38, 0x9d, + 0x45, 0x02, 0x9d, 0x80, 0xe2, 0x16, 0xe9, 0x70, 0x4b, 0x14, 0xd3, 0x9f, 0xe8, 0x65, 0x28, 0x6d, + 0x3b, 0x5e, 0x9b, 0x08, 0x33, 0x6d, 0xe1, 0x70, 0x2f, 0xa2, 0x7a, 0x86, 0x39, 0xd5, 0x1f, 0x29, + 0x3c, 0x6f, 0xd9, 0x7f, 0x50, 0x84, 0x61, 0xe3, 0xa3, 0x1d, 0x83, 0xe9, 0x19, 0x24, 0x4c, 0xcf, + 0xe5, 0xdc, 0xe6, 0x5b, 0x4f, 0xdb, 0xf3, 0x56, 0xca, 0xf6, 0x5c, 0xc9, 0x8f, 0xe5, 0x9e, 0xc6, + 0x27, 0x8a, 0xa1, 0x12, 0xb4, 0xe8, 0x36, 0x84, 0xda, 0x30, 0x03, 0x79, 0x7c, 0xc2, 0x15, 0x49, + 0x6e, 0x76, 0xf4, 0xf6, 0xee, 0x64, 0x45, 0xfd, 0xc5, 0x9a, 0x91, 0xfd, 0x4d, 0x0b, 0x4e, 0x1b, + 0x7d, 0x9c, 0x0b, 0xfc, 0xba, 0xcb, 0x3e, 0xed, 0x39, 0x18, 0x88, 0x3b, 0x2d, 0xb9, 0xd5, 0x51, + 0x23, 0xb5, 0xd6, 0x69, 0x11, 0xcc, 0x20, 0x74, 0xc7, 0xd2, 0x24, 0x51, 0xe4, 0x34, 0x48, 0x7a, + 0x73, 0xb3, 0xcc, 0x9b, 0xb1, 0x84, 0xa3, 0x10, 0x90, 0xe7, 0x44, 0xf1, 0x5a, 0xe8, 0xf8, 0x11, + 0x23, 0xbf, 0xe6, 0x36, 0x89, 0x18, 0xe0, 0xbf, 0xd5, 0xdf, 0x8c, 0xa1, 0x4f, 0xcc, 0x3e, 0x70, + 0x7b, 0x77, 0x12, 0x2d, 0x75, 0x51, 0xc2, 0x19, 0xd4, 0xed, 0xcf, 0x59, 0xf0, 0x40, 0xb6, 0x80, + 0x41, 0x4f, 0xc0, 0x20, 0xdf, 0xe7, 0x8a, 0xb7, 0xd3, 0x9f, 0x84, 0xb5, 0x62, 0x01, 0x45, 0xd3, + 0x50, 0x51, 0x0a, 0x4f, 0xbc, 0xe3, 0x49, 0x81, 0x5a, 0xd1, 0x5a, 0x52, 0xe3, 0xd0, 0x41, 0xa3, + 0x7f, 0x84, 0x09, 0xaa, 0x06, 0x8d, 0x6d, 0x0c, 0x19, 0xc4, 0xfe, 0x86, 0x05, 0x6f, 0xee, 0x47, + 0xec, 0x1d, 0x5d, 0x1f, 0xab, 0x70, 0xa6, 0x4e, 0x36, 0x9c, 0xb6, 0x17, 0x27, 0x39, 0x8a, 0x4e, + 0x3f, 0x2a, 0x1e, 0x3e, 0x33, 0x9f, 0x85, 0x84, 0xb3, 0x9f, 0xb5, 0xff, 0xab, 0x05, 0xe3, 0xc6, + 0x6b, 0x1d, 0xc3, 0xd6, 0xc9, 0x4f, 0x6e, 0x9d, 0x16, 0x73, 0x5b, 0xa6, 0x3d, 0xf6, 0x4e, 0x9f, + 0xb4, 0xe0, 0xac, 0x81, 0xb5, 0xec, 0xc4, 0xb5, 0xcd, 0x0b, 0x3b, 0xad, 0x90, 0x44, 0x11, 0x9d, + 0x52, 0x8f, 0x1a, 0xe2, 0x78, 0x76, 0x58, 0x50, 0x28, 0x5e, 0x21, 0x1d, 0x2e, 0x9b, 0x9f, 0x82, + 0x32, 0x5f, 0x73, 0x41, 0x28, 0x3e, 0x92, 0x7a, 0xb7, 0x15, 0xd1, 0x8e, 0x15, 0x06, 0xb2, 0x61, + 0x90, 0xc9, 0x5c, 0x2a, 0x83, 0xa8, 0x99, 0x00, 0xf4, 0xbb, 0x5f, 0x67, 0x2d, 0x58, 0x40, 0xec, + 0x28, 0xd1, 0x9d, 0xd5, 0x90, 0xb0, 0xf9, 0x50, 0xbf, 0xe8, 0x12, 0xaf, 0x1e, 0xd1, 0x6d, 0x9d, + 0xe3, 0xfb, 0x41, 0x2c, 0x76, 0x68, 0xc6, 0xb6, 0x6e, 0x46, 0x37, 0x63, 0x13, 0x87, 0x32, 0xf5, + 0x9c, 0x75, 0xe2, 0xf1, 0x11, 0x15, 0x4c, 0x97, 0x58, 0x0b, 0x16, 0x10, 0xfb, 0x76, 0x81, 0x6d, + 0x20, 0x95, 0x44, 0x23, 0xc7, 0xe1, 0x7d, 0x08, 0x13, 0x2a, 0x60, 0x35, 0x3f, 0x79, 0x4c, 0x7a, + 0x7b, 0x20, 0x5e, 0x4b, 0x69, 0x01, 0x9c, 0x2b, 0xd7, 0xbd, 0xbd, 0x10, 0x1f, 0x2c, 0xc2, 0x64, + 0xf2, 0x81, 0x2e, 0x25, 0x42, 0xb7, 0xbc, 0x06, 0xa3, 0xb4, 0x3f, 0xca, 0xc0, 0xc7, 0x26, 0x5e, + 0x0f, 0x39, 0x5c, 0x38, 0x4a, 0x39, 0x6c, 0xaa, 0x89, 0xe2, 0x3e, 0x6a, 0xe2, 0x09, 0x35, 0xea, + 0x03, 0x29, 0x99, 0x97, 0x54, 0x95, 0xe7, 0x60, 0x20, 0x8a, 0x49, 0x6b, 0xa2, 0x94, 0x14, 0xb3, + 0xd5, 0x98, 0xb4, 0x30, 0x83, 0xa0, 0x1f, 0x83, 0xf1, 0xd8, 0x09, 0x1b, 0x24, 0x0e, 0xc9, 0xb6, + 0xcb, 0x7c, 0x97, 0x6c, 0x3f, 0x5b, 0x99, 0x3d, 0x45, 0xad, 0xae, 0x35, 0x06, 0xc2, 0x12, 0x84, + 0xd3, 0xb8, 0xf6, 0xff, 0x28, 0xc0, 0x83, 0xc9, 0x4f, 0xa0, 0x15, 0xe3, 0x3b, 0x12, 0x8a, 0xf1, + 0xad, 0xa6, 0x62, 0xbc, 0xb3, 0x3b, 0xf9, 0x70, 0x8f, 0xc7, 0xbe, 0x6b, 0xf4, 0x26, 0x5a, 0x48, + 0x7d, 0x84, 0xe9, 0xe4, 0x47, 0xb8, 0xb3, 0x3b, 0xf9, 0x68, 0x8f, 0x77, 0x4c, 0x7d, 0xa5, 0x27, + 0x60, 0x30, 0x24, 0x4e, 0x14, 0xf8, 0xe2, 0x3b, 0xa9, 0xaf, 0x89, 0x59, 0x2b, 0x16, 0x50, 0xfb, + 0xeb, 0x95, 0xf4, 0x60, 0x2f, 0x70, 0x7f, 0x6c, 0x10, 0x22, 0x17, 0x06, 0xd8, 0xae, 0x8d, 0x4b, + 0x96, 0x2b, 0x87, 0x5b, 0x85, 0x54, 0x8b, 0x28, 0xd2, 0xb3, 0x65, 0xfa, 0xd5, 0x68, 0x13, 0x66, + 0x2c, 0xd0, 0x0e, 0x94, 0x6b, 0x72, 0x33, 0x55, 0xc8, 0xc3, 0xed, 0x28, 0xb6, 0x52, 0x9a, 0xe3, + 0x08, 0x15, 0xf7, 0x6a, 0x07, 0xa6, 0xb8, 0x21, 0x02, 0xc5, 0x86, 0x1b, 0x8b, 0xcf, 0x7a, 0xc8, + 0xed, 0xf2, 0x82, 0x6b, 0xbc, 0xe2, 0x10, 0xd5, 0x41, 0x0b, 0x6e, 0x8c, 0x29, 0x7d, 0xf4, 0x51, + 0x0b, 0x86, 0xa3, 0x5a, 0x73, 0x35, 0x0c, 0xb6, 0xdd, 0x3a, 0x09, 0x85, 0x8d, 0x79, 0x48, 0xc9, + 0x56, 0x9d, 0x5b, 0x96, 0x04, 0x35, 0x5f, 0xee, 0xbe, 0xd0, 0x10, 0x6c, 0xf2, 0xa5, 0x7b, 0xaf, + 0x07, 0xc5, 0xbb, 0xcf, 0x93, 0x1a, 0x5b, 0x71, 0x72, 0xcf, 0xcc, 0x66, 0xca, 0xa1, 0x6d, 0xee, + 0xf9, 0x76, 0x6d, 0x8b, 0xae, 0x37, 0xdd, 0xa1, 0x87, 0x6f, 0xef, 0x4e, 0x3e, 0x38, 0x97, 0xcd, + 0x13, 0xf7, 0xea, 0x0c, 0x1b, 0xb0, 0x56, 0xdb, 0xf3, 0x30, 0x79, 0xb5, 0x4d, 0x98, 0x47, 0x2c, + 0x87, 0x01, 0x5b, 0xd5, 0x04, 0x53, 0x03, 0x66, 0x40, 0xb0, 0xc9, 0x17, 0xbd, 0x0a, 0x83, 0x4d, + 0x27, 0x0e, 0xdd, 0x1d, 0xe1, 0x06, 0x3b, 0xe4, 0x2e, 0x68, 0x99, 0xd1, 0xd2, 0xcc, 0x99, 0xa2, + 0xe7, 0x8d, 0x58, 0x30, 0x42, 0x4d, 0x28, 0x35, 0x49, 0xd8, 0x20, 0x13, 0xe5, 0x3c, 0x5c, 0xfe, + 0xcb, 0x94, 0x94, 0x66, 0x58, 0xa1, 0xc6, 0x15, 0x6b, 0xc3, 0x9c, 0x0b, 0x7a, 0x19, 0xca, 0x11, + 0xf1, 0x48, 0x8d, 0x9a, 0x47, 0x15, 0xc6, 0xf1, 0x87, 0xfa, 0x34, 0x15, 0xa9, 0x5d, 0x52, 0x15, + 0x8f, 0xf2, 0x05, 0x26, 0xff, 0x61, 0x45, 0x92, 0x0e, 0x60, 0xcb, 0x6b, 0x37, 0x5c, 0x7f, 0x02, + 0xf2, 0x18, 0xc0, 0x55, 0x46, 0x2b, 0x35, 0x80, 0xbc, 0x11, 0x0b, 0x46, 0xf6, 0x7f, 0xb7, 0x00, + 0x25, 0x85, 0xda, 0x31, 0xd8, 0xc4, 0xaf, 0x26, 0x6d, 0xe2, 0xa5, 0x3c, 0x8d, 0x96, 0x1e, 0x66, + 0xf1, 0x6f, 0x54, 0x20, 0xa5, 0x0e, 0xae, 0x92, 0x28, 0x26, 0xf5, 0x37, 0x44, 0xf8, 0x1b, 0x22, + 0xfc, 0x0d, 0x11, 0xae, 0x44, 0xf8, 0x7a, 0x4a, 0x84, 0xbf, 0xdd, 0x58, 0xf5, 0xfa, 0x7c, 0xfd, + 0x15, 0x75, 0x00, 0x6f, 0xf6, 0xc0, 0x40, 0xa0, 0x92, 0xe0, 0x72, 0x75, 0xe5, 0x6a, 0xa6, 0xcc, + 0x7e, 0x25, 0x29, 0xb3, 0x0f, 0xcb, 0xe2, 0x6f, 0x82, 0x94, 0xfe, 0x5d, 0x0b, 0xde, 0x92, 0x94, + 0x5e, 0x72, 0xe6, 0x2c, 0x36, 0xfc, 0x20, 0x24, 0xf3, 0xee, 0xc6, 0x06, 0x09, 0x89, 0x5f, 0x23, + 0x91, 0xf2, 0xed, 0x58, 0xbd, 0x7c, 0x3b, 0xe8, 0x59, 0x18, 0xb9, 0x19, 0x05, 0xfe, 0x6a, 0xe0, + 0xfa, 0x42, 0x04, 0xd1, 0x1d, 0xc7, 0x89, 0xdb, 0xbb, 0x93, 0x23, 0x74, 0x44, 0x65, 0x3b, 0x4e, + 0x60, 0xa1, 0x39, 0x38, 0x79, 0xf3, 0xd5, 0x55, 0x27, 0x36, 0xbc, 0x09, 0x72, 0xdf, 0xcf, 0xce, + 0xa3, 0x2e, 0xbf, 0x98, 0x02, 0xe2, 0x6e, 0x7c, 0xfb, 0x1f, 0x14, 0xe0, 0xa1, 0xd4, 0x8b, 0x04, + 0x9e, 0x17, 0xb4, 0x63, 0xba, 0x27, 0x42, 0x5f, 0xb0, 0xe0, 0x44, 0x33, 0xe9, 0xb0, 0x88, 0x84, + 0xbb, 0xfb, 0x9d, 0xb9, 0xe9, 0x88, 0x94, 0x47, 0x64, 0x76, 0x42, 0x8c, 0xd0, 0x89, 0x14, 0x20, + 0xc2, 0x5d, 0x7d, 0x41, 0x2f, 0x43, 0xa5, 0xe9, 0xec, 0x5c, 0x6b, 0xd5, 0x9d, 0x58, 0x6e, 0x47, + 0x7b, 0x7b, 0x11, 0xda, 0xb1, 0xeb, 0x4d, 0xf1, 0xc8, 0x8d, 0xa9, 0x45, 0x3f, 0x5e, 0x09, 0xab, + 0x71, 0xe8, 0xfa, 0x0d, 0xee, 0xe4, 0x5c, 0x96, 0x64, 0xb0, 0xa6, 0x68, 0x7f, 0xde, 0x4a, 0x2b, + 0x29, 0x35, 0x3a, 0xa1, 0x13, 0x93, 0x46, 0x07, 0xbd, 0x0f, 0x4a, 0x74, 0xdf, 0x28, 0x47, 0xe5, + 0x46, 0x9e, 0x9a, 0xd3, 0xf8, 0x12, 0x5a, 0x89, 0xd2, 0x7f, 0x11, 0xe6, 0x4c, 0xed, 0x2f, 0x54, + 0xd2, 0xc6, 0x02, 0x3b, 0x9b, 0x3f, 0x0f, 0xd0, 0x08, 0xd6, 0x48, 0xb3, 0xe5, 0xd1, 0x61, 0xb1, + 0xd8, 0x01, 0x8f, 0x72, 0x95, 0x2c, 0x28, 0x08, 0x36, 0xb0, 0xd0, 0xcf, 0x59, 0x00, 0x0d, 0x39, + 0xe7, 0xa5, 0x21, 0x70, 0x2d, 0xcf, 0xd7, 0xd1, 0x2b, 0x4a, 0xf7, 0x45, 0x31, 0xc4, 0x06, 0x73, + 0xf4, 0xd3, 0x16, 0x94, 0x63, 0xd9, 0x7d, 0xae, 0x1a, 0xd7, 0xf2, 0xec, 0x89, 0x7c, 0x69, 0x6d, + 0x13, 0xa9, 0x21, 0x51, 0x7c, 0xd1, 0xcf, 0x58, 0x00, 0x51, 0xc7, 0xaf, 0xad, 0x06, 0x9e, 0x5b, + 0xeb, 0x08, 0x8d, 0x79, 0x3d, 0x57, 0x77, 0x8e, 0xa2, 0x3e, 0x3b, 0x46, 0x47, 0x43, 0xff, 0xc7, + 0x06, 0x67, 0xf4, 0x01, 0x28, 0x47, 0x62, 0xba, 0x09, 0x1d, 0xb9, 0x96, 0xaf, 0x53, 0x89, 0xd3, + 0x16, 0xe2, 0x55, 0xfc, 0xc3, 0x8a, 0x27, 0xfa, 0x05, 0x0b, 0xc6, 0x5b, 0x49, 0x37, 0xa1, 0x50, + 0x87, 0xf9, 0xc9, 0x80, 0x94, 0x1b, 0x92, 0x7b, 0x5b, 0x52, 0x8d, 0x38, 0xdd, 0x0b, 0x2a, 0x01, + 0xf5, 0x0c, 0x5e, 0x69, 0x71, 0x97, 0xe5, 0x90, 0x96, 0x80, 0x0b, 0x69, 0x20, 0xee, 0xc6, 0x47, + 0xab, 0x70, 0x9a, 0xf6, 0xae, 0xc3, 0xcd, 0x4f, 0xa9, 0x5e, 0x22, 0xa6, 0x0c, 0xcb, 0xb3, 0x8f, + 0x88, 0x19, 0xc2, 0xce, 0x3a, 0xd2, 0x38, 0x38, 0xf3, 0x49, 0xf4, 0x07, 0x16, 0x3c, 0xe2, 0x32, + 0x35, 0x60, 0x3a, 0xec, 0xb5, 0x46, 0x10, 0x07, 0xed, 0x24, 0x57, 0x59, 0xd1, 0x4b, 0xfd, 0xcc, + 0xbe, 0x59, 0xbc, 0xc1, 0x23, 0x8b, 0x7b, 0x74, 0x09, 0xef, 0xd9, 0x61, 0xf4, 0xc3, 0x30, 0x2a, + 0xd7, 0xc5, 0x2a, 0x15, 0xc1, 0x4c, 0xd1, 0x56, 0x66, 0x4f, 0xde, 0xde, 0x9d, 0x1c, 0x5d, 0x33, + 0x01, 0x38, 0x89, 0x67, 0xff, 0x87, 0x62, 0xe2, 0x94, 0x48, 0xf9, 0x30, 0x99, 0xb8, 0xa9, 0x49, + 0xff, 0x8f, 0x94, 0x9e, 0xb9, 0x8a, 0x1b, 0xe5, 0x5d, 0xd2, 0xe2, 0x46, 0x35, 0x45, 0xd8, 0x60, + 0x4e, 0x8d, 0xd2, 0x93, 0x4e, 0xda, 0x53, 0x2a, 0x24, 0xe0, 0xcb, 0x79, 0x76, 0xa9, 0xfb, 0x4c, + 0xef, 0x21, 0xd1, 0xb5, 0x93, 0x5d, 0x20, 0xdc, 0xdd, 0x25, 0xf4, 0x7e, 0xa8, 0x84, 0x2a, 0xb2, + 0xa5, 0x98, 0xc7, 0x56, 0x4d, 0x4e, 0x1b, 0xd1, 0x1d, 0x75, 0x00, 0xa4, 0x63, 0x58, 0x34, 0x47, + 0xfb, 0xf7, 0x92, 0x07, 0x63, 0x86, 0xec, 0xe8, 0xe3, 0xd0, 0xef, 0x53, 0x16, 0x0c, 0x87, 0x81, + 0xe7, 0xb9, 0x7e, 0x83, 0xca, 0x39, 0xa1, 0xac, 0xdf, 0x7d, 0x24, 0xfa, 0x52, 0x08, 0x34, 0x66, + 0x59, 0x63, 0xcd, 0x13, 0x9b, 0x1d, 0xb0, 0xff, 0xd4, 0x82, 0x89, 0x5e, 0xf2, 0x18, 0x11, 0x78, + 0x58, 0x0a, 0x1b, 0x35, 0x14, 0x2b, 0xfe, 0x3c, 0xf1, 0x88, 0x72, 0x9b, 0x97, 0x67, 0x1f, 0x17, + 0xaf, 0xf9, 0xf0, 0x6a, 0x6f, 0x54, 0xbc, 0x17, 0x1d, 0xf4, 0x12, 0x9c, 0x30, 0xde, 0x2b, 0x52, + 0x03, 0x53, 0x99, 0x9d, 0xa2, 0x06, 0xd0, 0x4c, 0x0a, 0x76, 0x67, 0x77, 0xf2, 0x81, 0x74, 0x9b, + 0x50, 0x18, 0x5d, 0x74, 0xec, 0x2f, 0x17, 0xd2, 0x5f, 0x4b, 0xe9, 0xfa, 0xd7, 0xad, 0x2e, 0x6f, + 0xc2, 0x3b, 0x8f, 0x42, 0xbf, 0x32, 0xbf, 0x83, 0x0a, 0xc3, 0xe8, 0x8d, 0x73, 0x0f, 0x8f, 0xed, + 0xed, 0xff, 0x38, 0x00, 0x7b, 0xf4, 0xac, 0x0f, 0xe3, 0xfd, 0xc0, 0xe7, 0xa8, 0x9f, 0xb0, 0xd4, + 0x81, 0x19, 0x5f, 0xc3, 0xf5, 0xa3, 0x1a, 0x7b, 0xbe, 0x7f, 0x8a, 0x78, 0xe8, 0x88, 0xf2, 0xa2, + 0x27, 0x8f, 0xe6, 0xd0, 0x17, 0xad, 0xe4, 0x91, 0x1f, 0x0f, 0x6a, 0x74, 0x8f, 0xac, 0x4f, 0xc6, + 0x39, 0x22, 0xef, 0x98, 0x3e, 0x7d, 0xea, 0x75, 0xc2, 0x38, 0x05, 0xb0, 0xe1, 0xfa, 0x8e, 0xe7, + 0xbe, 0x46, 0x77, 0x47, 0x25, 0xa6, 0xe0, 0x99, 0xc5, 0x74, 0x51, 0xb5, 0x62, 0x03, 0xe3, 0xec, + 0xdf, 0x86, 0x61, 0xe3, 0xcd, 0x33, 0x22, 0x5e, 0x4e, 0x9b, 0x11, 0x2f, 0x15, 0x23, 0x50, 0xe5, + 0xec, 0xdb, 0xe1, 0x44, 0xba, 0x83, 0x07, 0x79, 0xde, 0xfe, 0x3f, 0x43, 0xe9, 0x33, 0xb8, 0x35, + 0x12, 0x36, 0x69, 0xd7, 0xde, 0x70, 0x6c, 0xbd, 0xe1, 0xd8, 0x7a, 0xc3, 0xb1, 0x65, 0x9e, 0x4d, + 0x08, 0xa7, 0xcd, 0xd0, 0x31, 0x39, 0x6d, 0x12, 0x6e, 0xa8, 0x72, 0xee, 0x6e, 0x28, 0xfb, 0xa3, + 0x5d, 0x9e, 0xfb, 0xb5, 0x90, 0x10, 0x14, 0x40, 0xc9, 0x0f, 0xea, 0x44, 0xda, 0xb8, 0x97, 0xf3, + 0x31, 0xd8, 0xae, 0x06, 0x75, 0x23, 0x5c, 0x9c, 0xfe, 0x8b, 0x30, 0xe7, 0x63, 0x7f, 0x64, 0x10, + 0x12, 0xe6, 0x24, 0xff, 0xee, 0x3f, 0x00, 0x43, 0x21, 0x69, 0x05, 0xd7, 0xf0, 0x92, 0xd0, 0x65, + 0x3a, 0xa3, 0x84, 0x37, 0x63, 0x09, 0xa7, 0x3a, 0xaf, 0xe5, 0xc4, 0x9b, 0x42, 0x99, 0x29, 0x9d, + 0xb7, 0xea, 0xc4, 0x9b, 0x98, 0x41, 0xd0, 0xdb, 0x61, 0x2c, 0x4e, 0x1c, 0x85, 0x8b, 0x23, 0xdf, + 0x07, 0x04, 0xee, 0x58, 0xf2, 0xa0, 0x1c, 0xa7, 0xb0, 0xd1, 0xab, 0x30, 0xb0, 0x49, 0xbc, 0xa6, + 0xf8, 0xf4, 0xd5, 0xfc, 0x74, 0x0d, 0x7b, 0xd7, 0x4b, 0xc4, 0x6b, 0x72, 0x49, 0x48, 0x7f, 0x61, + 0xc6, 0x8a, 0xce, 0xfb, 0xca, 0x56, 0x3b, 0x8a, 0x83, 0xa6, 0xfb, 0x9a, 0xf4, 0x74, 0xbe, 0x33, + 0x67, 0xc6, 0x57, 0x24, 0x7d, 0xee, 0x52, 0x52, 0x7f, 0xb1, 0xe6, 0xcc, 0xfa, 0x51, 0x77, 0x43, + 0x36, 0x65, 0x3a, 0xc2, 0x61, 0x99, 0x77, 0x3f, 0xe6, 0x25, 0x7d, 0xde, 0x0f, 0xf5, 0x17, 0x6b, + 0xce, 0xa8, 0xa3, 0xd6, 0xdf, 0x30, 0xeb, 0xc3, 0xb5, 0x9c, 0xfb, 0xc0, 0xd7, 0x5e, 0xe6, 0x3a, + 0x7c, 0x1c, 0x4a, 0xb5, 0x4d, 0x27, 0x8c, 0x27, 0x46, 0xd8, 0xa4, 0x51, 0xb3, 0x78, 0x8e, 0x36, + 0x62, 0x0e, 0x43, 0x8f, 0x42, 0x31, 0x24, 0x1b, 0x2c, 0x3a, 0xd9, 0x88, 0x8b, 0xc2, 0x64, 0x03, + 0xd3, 0x76, 0x65, 0x97, 0x8d, 0xf5, 0x0c, 0x98, 0xfb, 0xe5, 0x42, 0xd2, 0xb0, 0x4b, 0x8e, 0x0c, + 0x5f, 0x0f, 0xb5, 0x76, 0x18, 0x49, 0x07, 0x99, 0xb1, 0x1e, 0x58, 0x33, 0x96, 0x70, 0xf4, 0x21, + 0x0b, 0x86, 0x6e, 0x46, 0x81, 0xef, 0x93, 0x58, 0x28, 0xd1, 0xeb, 0x39, 0x0f, 0xd6, 0x65, 0x4e, + 0x5d, 0xf7, 0x41, 0x34, 0x60, 0xc9, 0x97, 0x76, 0x97, 0xec, 0xd4, 0xbc, 0x76, 0xbd, 0x2b, 0x18, + 0xe6, 0x02, 0x6f, 0xc6, 0x12, 0x4e, 0x51, 0x5d, 0x9f, 0xa3, 0x0e, 0x24, 0x51, 0x17, 0x7d, 0x81, + 0x2a, 0xe0, 0xf6, 0xaf, 0x95, 0xe1, 0x4c, 0xe6, 0xf2, 0xa1, 0x26, 0x17, 0x33, 0x6a, 0x2e, 0xba, + 0x1e, 0x91, 0x61, 0x60, 0xcc, 0xe4, 0xba, 0xae, 0x5a, 0xb1, 0x81, 0x81, 0x7e, 0x0a, 0xa0, 0xe5, + 0x84, 0x4e, 0x93, 0x28, 0x07, 0xf6, 0xa1, 0x2d, 0x1b, 0xda, 0x8f, 0x55, 0x49, 0x53, 0x6f, 0xe2, + 0x55, 0x53, 0x84, 0x0d, 0x96, 0xe8, 0x39, 0x18, 0x0e, 0x89, 0x47, 0x9c, 0x88, 0x85, 0xbf, 0xa7, + 0x73, 0x79, 0xb0, 0x06, 0x61, 0x13, 0x0f, 0x3d, 0xa1, 0x22, 0xe6, 0x52, 0x91, 0x43, 0xc9, 0xa8, + 0x39, 0xf4, 0x69, 0x0b, 0xc6, 0x36, 0x5c, 0x8f, 0x68, 0xee, 0x22, 0xf3, 0x66, 0xe5, 0xf0, 0x2f, + 0x79, 0xd1, 0xa4, 0xab, 0x65, 0x68, 0xa2, 0x39, 0xc2, 0x29, 0xf6, 0xf4, 0x33, 0x6f, 0x93, 0x90, + 0x09, 0xdf, 0xc1, 0xe4, 0x67, 0xbe, 0xce, 0x9b, 0xb1, 0x84, 0xa3, 0x19, 0x18, 0x6f, 0x39, 0x51, + 0x34, 0x17, 0x92, 0x3a, 0xf1, 0x63, 0xd7, 0xf1, 0x78, 0x5e, 0x4c, 0x59, 0x87, 0x93, 0xaf, 0x26, + 0xc1, 0x38, 0x8d, 0x8f, 0xde, 0x05, 0x0f, 0x72, 0x0f, 0xd1, 0xb2, 0x1b, 0x45, 0xae, 0xdf, 0xd0, + 0xd3, 0x40, 0x38, 0xca, 0x26, 0x05, 0xa9, 0x07, 0x17, 0xb3, 0xd1, 0x70, 0xaf, 0xe7, 0xd1, 0x53, + 0x50, 0x8e, 0xb6, 0xdc, 0xd6, 0x5c, 0x58, 0x8f, 0xd8, 0xe9, 0x50, 0x59, 0xbb, 0x65, 0xab, 0xa2, + 0x1d, 0x2b, 0x0c, 0x54, 0x83, 0x11, 0xfe, 0x49, 0x78, 0xc8, 0x9f, 0x90, 0xa0, 0x4f, 0xf7, 0x54, + 0xe4, 0x22, 0xcd, 0x73, 0x0a, 0x3b, 0xb7, 0x2e, 0xc8, 0xb3, 0x2a, 0x7e, 0xb4, 0x72, 0xdd, 0x20, + 0x83, 0x13, 0x44, 0x93, 0x7b, 0xba, 0xe1, 0x3e, 0xf6, 0x74, 0xcf, 0xc1, 0xf0, 0x56, 0x7b, 0x9d, + 0x88, 0x91, 0x17, 0x82, 0x4d, 0xcd, 0xbe, 0x2b, 0x1a, 0x84, 0x4d, 0x3c, 0x16, 0x6d, 0xd9, 0x72, + 0xc5, 0xbf, 0x68, 0x62, 0xd4, 0x88, 0xb6, 0x5c, 0x5d, 0x94, 0xcd, 0xd8, 0xc4, 0xa1, 0x5d, 0xa3, + 0x63, 0xb1, 0x46, 0x22, 0x96, 0x4c, 0x41, 0x87, 0x4b, 0x75, 0xad, 0x2a, 0x01, 0x58, 0xe3, 0xa0, + 0x55, 0x38, 0x4d, 0xff, 0x54, 0x59, 0x9a, 0xeb, 0x75, 0xc7, 0x73, 0xeb, 0x3c, 0xf4, 0x6f, 0x3c, + 0xe9, 0xdf, 0xac, 0x66, 0xe0, 0xe0, 0xcc, 0x27, 0xed, 0x5f, 0x2c, 0x24, 0x3d, 0x27, 0xa6, 0x08, + 0x43, 0x11, 0x15, 0x54, 0xf1, 0x75, 0x27, 0x94, 0x06, 0xcf, 0x21, 0x93, 0x9b, 0x04, 0xdd, 0xeb, + 0x4e, 0x68, 0x8a, 0x3c, 0xc6, 0x00, 0x4b, 0x4e, 0xe8, 0x26, 0x0c, 0xc4, 0x9e, 0x93, 0x53, 0x36, + 0xa4, 0xc1, 0x51, 0x3b, 0xb2, 0x96, 0x66, 0x22, 0xcc, 0x78, 0xa0, 0x47, 0xe8, 0xee, 0x6d, 0x5d, + 0x9e, 0xb4, 0x89, 0x0d, 0xd7, 0x7a, 0x84, 0x59, 0xab, 0xfd, 0x67, 0xc3, 0x19, 0x5a, 0x47, 0x19, + 0x02, 0xe8, 0x3c, 0x00, 0x9d, 0x34, 0xab, 0x21, 0xd9, 0x70, 0x77, 0x84, 0x21, 0xa6, 0x24, 0xdb, + 0x55, 0x05, 0xc1, 0x06, 0x96, 0x7c, 0xa6, 0xda, 0xde, 0xa0, 0xcf, 0x14, 0xba, 0x9f, 0xe1, 0x10, + 0x6c, 0x60, 0xa1, 0x67, 0x61, 0xd0, 0x6d, 0x3a, 0x0d, 0x15, 0x08, 0xfc, 0x08, 0x15, 0x69, 0x8b, + 0xac, 0xe5, 0xce, 0xee, 0xe4, 0x98, 0xea, 0x10, 0x6b, 0xc2, 0x02, 0x17, 0x7d, 0xd9, 0x82, 0x91, + 0x5a, 0xd0, 0x6c, 0x06, 0x3e, 0xdf, 0x3e, 0x0b, 0x5f, 0xc0, 0xcd, 0xa3, 0x32, 0x93, 0xa6, 0xe6, + 0x0c, 0x66, 0xdc, 0x19, 0xa0, 0xd2, 0x36, 0x4d, 0x10, 0x4e, 0xf4, 0xca, 0x94, 0x7c, 0xa5, 0x7d, + 0x24, 0xdf, 0xaf, 0x5b, 0x70, 0x92, 0x3f, 0x6b, 0xec, 0xea, 0x45, 0x86, 0x62, 0x70, 0xc4, 0xaf, + 0xd5, 0xe5, 0xe8, 0x50, 0xce, 0xde, 0x2e, 0x38, 0xee, 0xee, 0x24, 0x5a, 0x80, 0x93, 0x1b, 0x41, + 0x58, 0x23, 0xe6, 0x40, 0x08, 0xb1, 0xad, 0x08, 0x5d, 0x4c, 0x23, 0xe0, 0xee, 0x67, 0xd0, 0x75, + 0x78, 0xc0, 0x68, 0x34, 0xc7, 0x81, 0x4b, 0xee, 0xc7, 0x04, 0xb5, 0x07, 0x2e, 0x66, 0x62, 0xe1, + 0x1e, 0x4f, 0x27, 0x85, 0x64, 0xa5, 0x0f, 0x21, 0xf9, 0x0a, 0x3c, 0x54, 0xeb, 0x1e, 0x99, 0xed, + 0xa8, 0xbd, 0x1e, 0x71, 0x39, 0x5e, 0x9e, 0xfd, 0x3e, 0x41, 0xe0, 0xa1, 0xb9, 0x5e, 0x88, 0xb8, + 0x37, 0x0d, 0xf4, 0x3e, 0x28, 0x87, 0x84, 0x7d, 0x95, 0x48, 0xa4, 0xeb, 0x1d, 0xd2, 0xdb, 0xa1, + 0x2d, 0x78, 0x4e, 0x56, 0x6b, 0x26, 0xd1, 0x10, 0x61, 0xc5, 0x11, 0xdd, 0x82, 0xa1, 0x96, 0x13, + 0xd7, 0x36, 0x45, 0x92, 0xde, 0xa1, 0x7d, 0xf3, 0x8a, 0x39, 0x3b, 0x4a, 0x31, 0xd2, 0xfa, 0x39, + 0x13, 0x2c, 0xb9, 0x51, 0x5b, 0xad, 0x16, 0x34, 0x5b, 0x81, 0x4f, 0xfc, 0x58, 0x2a, 0x91, 0x31, + 0x7e, 0xde, 0x21, 0x5b, 0xb1, 0x81, 0x41, 0x35, 0x02, 0xf3, 0xfd, 0xdd, 0x70, 0xe3, 0xcd, 0xa0, + 0x1d, 0xcb, 0xad, 0xac, 0xd0, 0x26, 0x4a, 0x23, 0x2c, 0x65, 0xe0, 0xe0, 0xcc, 0x27, 0xd3, 0xea, + 0x6f, 0xfc, 0xee, 0xd4, 0xdf, 0x89, 0xfd, 0xd5, 0xdf, 0xd9, 0x77, 0xc0, 0xc9, 0x2e, 0xa1, 0x71, + 0x20, 0x07, 0xdf, 0x3c, 0x3c, 0x90, 0xbd, 0x3c, 0x0f, 0xe4, 0xe6, 0xfb, 0xb5, 0x54, 0x9c, 0xb7, + 0xb1, 0xe5, 0xe9, 0xc3, 0x65, 0xec, 0x40, 0x91, 0xf8, 0xdb, 0x42, 0x5b, 0x5d, 0x3c, 0xdc, 0x2c, + 0xb9, 0xe0, 0x6f, 0x73, 0xe9, 0xc2, 0xfc, 0x62, 0x17, 0xfc, 0x6d, 0x4c, 0x69, 0xa3, 0xcf, 0x5a, + 0x09, 0x83, 0x9c, 0x3b, 0x9a, 0xdf, 0x73, 0x24, 0x7b, 0xbc, 0xbe, 0x6d, 0x74, 0xfb, 0xf7, 0x0b, + 0x70, 0x6e, 0x3f, 0x22, 0x7d, 0x0c, 0xdf, 0xe3, 0x30, 0x18, 0xb1, 0xc8, 0x0d, 0x21, 0xfe, 0x87, + 0xe9, 0xaa, 0xe0, 0xb1, 0x1c, 0xaf, 0x60, 0x01, 0x42, 0x1e, 0x14, 0x9b, 0x4e, 0x4b, 0xf8, 0x1f, + 0x17, 0x0f, 0x9b, 0x0f, 0x47, 0xff, 0x3b, 0xde, 0xb2, 0xd3, 0xe2, 0xd3, 0xd3, 0x68, 0xc0, 0x94, + 0x0d, 0x8a, 0xa1, 0xe4, 0x84, 0xa1, 0x23, 0xc3, 0x04, 0xae, 0xe4, 0xc3, 0x6f, 0x86, 0x92, 0xe4, + 0xa7, 0xac, 0x89, 0x26, 0xcc, 0x99, 0xd9, 0xbf, 0x50, 0x4e, 0x24, 0x4f, 0xb1, 0xd8, 0x8f, 0x08, + 0x06, 0x85, 0xdb, 0xd1, 0xca, 0x3b, 0x0d, 0x91, 0x67, 0x27, 0xb3, 0x1d, 0xbd, 0xa8, 0xf1, 0x20, + 0x58, 0xa1, 0x8f, 0x5b, 0xac, 0x92, 0x82, 0xcc, 0x48, 0x13, 0xbb, 0xe4, 0xa3, 0x29, 0xec, 0x60, + 0xd6, 0x67, 0x90, 0x8d, 0xd8, 0xe4, 0x2e, 0x2a, 0xa2, 0xb0, 0xdd, 0x41, 0x77, 0x45, 0x14, 0x66, + 0xed, 0x4b, 0x38, 0xda, 0xc9, 0x88, 0xf1, 0xc8, 0x21, 0x1b, 0xbf, 0x8f, 0xa8, 0x8e, 0x2f, 0x5a, + 0x70, 0xd2, 0x4d, 0x1f, 0xd6, 0x8b, 0x3d, 0xe5, 0x8d, 0x7c, 0x7c, 0x84, 0xdd, 0xb1, 0x00, 0xca, + 0x70, 0xe8, 0x02, 0xe1, 0xee, 0xce, 0xa0, 0x3a, 0x0c, 0xb8, 0xfe, 0x46, 0x20, 0xcc, 0xa5, 0xd9, + 0xc3, 0x75, 0x6a, 0xd1, 0xdf, 0x08, 0xf4, 0x6a, 0xa6, 0xff, 0x30, 0xa3, 0x8e, 0x96, 0xe0, 0xb4, + 0xcc, 0x9f, 0xb9, 0xe4, 0x46, 0x71, 0x10, 0x76, 0x96, 0xdc, 0xa6, 0x1b, 0x33, 0x53, 0xa7, 0x38, + 0x3b, 0x41, 0x35, 0x11, 0xce, 0x80, 0xe3, 0xcc, 0xa7, 0xd0, 0x6b, 0x30, 0x24, 0x0f, 0xc8, 0xcb, + 0x79, 0xec, 0xcf, 0xbb, 0xe7, 0xbf, 0x9a, 0x4c, 0x55, 0x71, 0x42, 0x2e, 0x19, 0xa2, 0x8f, 0x59, + 0x30, 0xc6, 0x7f, 0x5f, 0xea, 0xd4, 0x79, 0xca, 0x5e, 0x25, 0x8f, 0x28, 0xf8, 0x6a, 0x82, 0xe6, + 0x2c, 0xba, 0xbd, 0x3b, 0x39, 0x96, 0x6c, 0xc3, 0x29, 0xbe, 0xf6, 0x97, 0x47, 0xa0, 0x3b, 0xa4, + 0x20, 0x19, 0x3f, 0x60, 0x1d, 0x77, 0xfc, 0x00, 0xdd, 0xa5, 0x45, 0xfa, 0xe8, 0x3f, 0x87, 0x65, + 0x26, 0xb8, 0xea, 0x63, 0xdd, 0x8e, 0x5f, 0xc3, 0x8c, 0x07, 0x0a, 0x61, 0x70, 0x93, 0x38, 0x5e, + 0xbc, 0x99, 0xcf, 0x09, 0xd4, 0x25, 0x46, 0x2b, 0x9d, 0x7f, 0xc7, 0x5b, 0xb1, 0xe0, 0x84, 0x76, + 0x60, 0x68, 0x93, 0xcf, 0x45, 0xb1, 0x71, 0x5a, 0x3e, 0xec, 0xe0, 0x26, 0x26, 0xb8, 0x9e, 0x79, + 0xa2, 0x01, 0x4b, 0x76, 0x2c, 0x56, 0xcd, 0x88, 0xa6, 0xe1, 0x52, 0x24, 0xbf, 0xd4, 0xc3, 0xfe, + 0x43, 0x69, 0xde, 0x0b, 0x23, 0x21, 0xa9, 0x05, 0x7e, 0xcd, 0xf5, 0x48, 0x7d, 0x46, 0x9e, 0x2e, + 0x1d, 0x24, 0xe3, 0x8c, 0xb9, 0x66, 0xb0, 0x41, 0x03, 0x27, 0x28, 0xb2, 0x45, 0xa6, 0xb2, 0xd0, + 0xe9, 0x07, 0x21, 0xe2, 0x14, 0x61, 0x29, 0xa7, 0x9c, 0x77, 0x46, 0x93, 0x2f, 0xb2, 0x64, 0x1b, + 0x4e, 0xf1, 0x45, 0x2f, 0x01, 0x04, 0xeb, 0x3c, 0x20, 0x6d, 0x26, 0x16, 0x47, 0x0a, 0x07, 0x79, + 0xd5, 0x31, 0x9e, 0xb9, 0x2a, 0x29, 0x60, 0x83, 0x1a, 0xba, 0x02, 0xc0, 0x97, 0xcd, 0x5a, 0xa7, + 0x25, 0x77, 0x57, 0x32, 0x65, 0x10, 0xaa, 0x0a, 0x72, 0x67, 0x77, 0xb2, 0xdb, 0x81, 0xcb, 0xa2, + 0x6e, 0x8c, 0xc7, 0xd1, 0x4f, 0xc2, 0x50, 0xd4, 0x6e, 0x36, 0x1d, 0x75, 0xe0, 0x90, 0x63, 0x2e, + 0x2c, 0xa7, 0x6b, 0x48, 0x45, 0xde, 0x80, 0x25, 0x47, 0x74, 0x93, 0xca, 0x77, 0x21, 0x9e, 0xf8, + 0x2a, 0xe2, 0xe6, 0x09, 0x77, 0xab, 0xbd, 0x4d, 0xee, 0x36, 0x70, 0x06, 0xce, 0x9d, 0xdd, 0xc9, + 0x07, 0x92, 0xed, 0x4b, 0x81, 0xc8, 0x4e, 0xcd, 0xa4, 0x89, 0x2e, 0xcb, 0xa2, 0x54, 0xf4, 0xb5, + 0x65, 0xad, 0x94, 0x27, 0x75, 0x51, 0x2a, 0xd6, 0xdc, 0x7b, 0xcc, 0xcc, 0x87, 0xd1, 0x32, 0x9c, + 0xaa, 0x05, 0x7e, 0x1c, 0x06, 0x9e, 0xc7, 0x8b, 0xb2, 0xf1, 0x8d, 0x2e, 0x3f, 0x90, 0x78, 0x58, + 0x74, 0xfb, 0xd4, 0x5c, 0x37, 0x0a, 0xce, 0x7a, 0x8e, 0x1a, 0xe4, 0x69, 0xe5, 0x30, 0x96, 0xcb, + 0x59, 0x75, 0x82, 0xa6, 0x90, 0x50, 0xca, 0x87, 0xbc, 0x8f, 0x9a, 0xf0, 0x93, 0x27, 0x96, 0xe2, + 0x8b, 0x3d, 0x0b, 0x23, 0x64, 0x27, 0x26, 0xa1, 0xef, 0x78, 0xd7, 0xf0, 0x92, 0xf4, 0xfe, 0xb3, + 0x85, 0x79, 0xc1, 0x68, 0xc7, 0x09, 0x2c, 0x64, 0x2b, 0x97, 0x93, 0x91, 0x06, 0xce, 0x5d, 0x4e, + 0xd2, 0xc1, 0x64, 0x7f, 0xb5, 0x98, 0x30, 0x58, 0xef, 0xc9, 0xf9, 0x28, 0xab, 0x37, 0x24, 0x0b, + 0x33, 0x31, 0x80, 0xd8, 0x88, 0xe5, 0xc9, 0x59, 0xd5, 0x1b, 0x5a, 0x31, 0x19, 0xe1, 0x24, 0x5f, + 0xb4, 0x05, 0xa5, 0xcd, 0x20, 0x8a, 0xe5, 0xf6, 0xec, 0x90, 0x3b, 0xc1, 0x4b, 0x41, 0x14, 0x33, + 0x2b, 0x4b, 0xbd, 0x36, 0x6d, 0x89, 0x30, 0xe7, 0x41, 0xf7, 0xe8, 0xd1, 0xa6, 0x13, 0xd6, 0xa3, + 0x39, 0x56, 0xb4, 0x61, 0x80, 0x99, 0x57, 0xca, 0x98, 0xae, 0x6a, 0x10, 0x36, 0xf1, 0xec, 0x3f, + 0xb7, 0x12, 0x47, 0x44, 0x37, 0x58, 0x04, 0xfe, 0x36, 0xf1, 0xa9, 0x88, 0x32, 0x63, 0xfe, 0x7e, + 0x38, 0x95, 0xcf, 0xfc, 0x96, 0x5e, 0xf5, 0x13, 0x6f, 0x51, 0x0a, 0x53, 0x8c, 0x84, 0x11, 0x1e, + 0xf8, 0x41, 0x2b, 0x99, 0x98, 0x5e, 0xc8, 0x63, 0xdf, 0x66, 0x16, 0x67, 0xd8, 0x37, 0xc7, 0xdd, + 0xfe, 0xac, 0x05, 0x43, 0xb3, 0x4e, 0x6d, 0x2b, 0xd8, 0xd8, 0x40, 0x4f, 0x41, 0xb9, 0xde, 0x0e, + 0xcd, 0x1c, 0x79, 0xe5, 0xf9, 0x99, 0x17, 0xed, 0x58, 0x61, 0xd0, 0xa9, 0xbf, 0xe1, 0xd4, 0x64, + 0x89, 0x86, 0x22, 0x9f, 0xfa, 0x17, 0x59, 0x0b, 0x16, 0x10, 0x3a, 0xfc, 0x4d, 0x67, 0x47, 0x3e, + 0x9c, 0x3e, 0x9f, 0x5a, 0xd6, 0x20, 0x6c, 0xe2, 0xd9, 0xff, 0xce, 0x82, 0x89, 0x59, 0x27, 0x72, + 0x6b, 0x33, 0xed, 0x78, 0x73, 0xd6, 0x8d, 0xd7, 0xdb, 0xb5, 0x2d, 0x12, 0xf3, 0x52, 0x1e, 0xb4, + 0x97, 0xed, 0x88, 0xae, 0x40, 0xb5, 0x5d, 0x56, 0xbd, 0xbc, 0x26, 0xda, 0xb1, 0xc2, 0x40, 0xaf, + 0xc1, 0x70, 0xcb, 0x89, 0xa2, 0x5b, 0x41, 0x58, 0xc7, 0x64, 0x23, 0x9f, 0x62, 0x3f, 0x55, 0x52, + 0x0b, 0x49, 0x8c, 0xc9, 0x86, 0x88, 0xf6, 0xd0, 0xf4, 0xb1, 0xc9, 0xcc, 0xfe, 0x39, 0x0b, 0x4e, + 0xcf, 0x12, 0x27, 0x24, 0x21, 0xab, 0x0d, 0xa4, 0x5e, 0x04, 0xbd, 0x0a, 0xe5, 0x98, 0xb6, 0xd0, + 0x1e, 0x59, 0xf9, 0xf6, 0x88, 0xc5, 0x69, 0xac, 0x09, 0xe2, 0x58, 0xb1, 0xb1, 0x3f, 0x65, 0xc1, + 0x43, 0x59, 0x7d, 0x99, 0xf3, 0x82, 0x76, 0xfd, 0x5e, 0x74, 0xe8, 0xef, 0x5b, 0x30, 0xc2, 0xce, + 0xbe, 0xe7, 0x49, 0xec, 0xb8, 0x5e, 0x57, 0x5d, 0x42, 0xab, 0xcf, 0xba, 0x84, 0xe7, 0x60, 0x60, + 0x33, 0x68, 0x92, 0x74, 0xdc, 0xc6, 0xa5, 0xa0, 0x49, 0x30, 0x83, 0xa0, 0x67, 0xe8, 0x24, 0x74, + 0xfd, 0xd8, 0xa1, 0xcb, 0x51, 0x9e, 0x0d, 0x8c, 0xf3, 0x09, 0xa8, 0x9a, 0xb1, 0x89, 0x63, 0xff, + 0xdb, 0x0a, 0x0c, 0x89, 0x20, 0xa3, 0xbe, 0x4b, 0xcb, 0x48, 0x17, 0x4e, 0xa1, 0xa7, 0x0b, 0x27, + 0x82, 0xc1, 0x1a, 0x2b, 0x90, 0x2a, 0xcc, 0xf3, 0x2b, 0xb9, 0x44, 0xa5, 0xf1, 0x9a, 0xab, 0xba, + 0x5b, 0xfc, 0x3f, 0x16, 0xac, 0xd0, 0x67, 0x2c, 0x18, 0xaf, 0x05, 0xbe, 0x4f, 0x6a, 0xda, 0x76, + 0x1c, 0xc8, 0x23, 0xf8, 0x68, 0x2e, 0x49, 0x54, 0x1f, 0xab, 0xa6, 0x00, 0x38, 0xcd, 0x1e, 0xbd, + 0x00, 0xa3, 0x7c, 0xcc, 0xae, 0x27, 0x0e, 0x34, 0x74, 0xb9, 0x3a, 0x13, 0x88, 0x93, 0xb8, 0x68, + 0x8a, 0x1f, 0x0c, 0x89, 0xc2, 0x70, 0x83, 0xda, 0xef, 0x6b, 0x94, 0x84, 0x33, 0x30, 0x50, 0x08, + 0x28, 0x24, 0x1b, 0x21, 0x89, 0x36, 0x45, 0x10, 0x16, 0xb3, 0x5b, 0x87, 0xee, 0xae, 0x28, 0x04, + 0xee, 0xa2, 0x84, 0x33, 0xa8, 0xa3, 0x2d, 0xe1, 0x43, 0x28, 0xe7, 0x21, 0xcf, 0xc5, 0x67, 0xee, + 0xe9, 0x4a, 0x98, 0x84, 0x12, 0x53, 0x5d, 0xcc, 0x5e, 0x2e, 0xf2, 0x44, 0x44, 0xa6, 0xd8, 0x30, + 0x6f, 0x47, 0xf3, 0x70, 0x22, 0x55, 0x6c, 0x2f, 0x12, 0x07, 0x0f, 0x2a, 0xe9, 0x2c, 0x55, 0xa6, + 0x2f, 0xc2, 0x5d, 0x4f, 0x98, 0xfe, 0xa5, 0xe1, 0x7d, 0xfc, 0x4b, 0x1d, 0x15, 0xea, 0xcb, 0x8f, + 0x04, 0x5e, 0xcc, 0x65, 0x00, 0xfa, 0x8a, 0xeb, 0xfd, 0x64, 0x2a, 0xae, 0x77, 0x94, 0x75, 0xe0, + 0x7a, 0x3e, 0x1d, 0x38, 0x78, 0x10, 0xef, 0xbd, 0x0c, 0xca, 0xfd, 0xdf, 0x16, 0xc8, 0xef, 0x3a, + 0xe7, 0xd4, 0x36, 0x09, 0x9d, 0x32, 0xe8, 0xed, 0x30, 0xa6, 0x5c, 0x13, 0xdc, 0x24, 0xb2, 0xd8, + 0xac, 0x51, 0xb6, 0x33, 0x4e, 0x40, 0x71, 0x0a, 0x1b, 0x4d, 0x43, 0x85, 0x8e, 0x13, 0x7f, 0x94, + 0xeb, 0x7d, 0xe5, 0xfe, 0x98, 0x59, 0x5d, 0x14, 0x4f, 0x69, 0x1c, 0x14, 0xc0, 0x49, 0xcf, 0x89, + 0x62, 0xd6, 0x83, 0x6a, 0xc7, 0xaf, 0xdd, 0x65, 0x49, 0x16, 0x96, 0xd9, 0xb4, 0x94, 0x26, 0x84, + 0xbb, 0x69, 0xdb, 0xff, 0xa9, 0x04, 0xa3, 0x09, 0xc9, 0x78, 0x40, 0x83, 0xe1, 0x29, 0x28, 0x4b, + 0x1d, 0x9e, 0xae, 0x3d, 0xa5, 0x14, 0xbd, 0xc2, 0xa0, 0x4a, 0x6b, 0x5d, 0x6b, 0xd5, 0xb4, 0x81, + 0x63, 0x28, 0x5c, 0x6c, 0xe2, 0x31, 0xa1, 0x1c, 0x7b, 0xd1, 0x9c, 0xe7, 0x12, 0x3f, 0xe6, 0xdd, + 0xcc, 0x47, 0x28, 0xaf, 0x2d, 0x55, 0x4d, 0xa2, 0x5a, 0x28, 0xa7, 0x00, 0x38, 0xcd, 0x1e, 0x7d, + 0xc4, 0x82, 0x51, 0xe7, 0x56, 0xa4, 0xab, 0x78, 0x8b, 0x08, 0xde, 0x43, 0x2a, 0xa9, 0x44, 0x61, + 0x70, 0xee, 0xd5, 0x4f, 0x34, 0xe1, 0x24, 0x53, 0xf4, 0xba, 0x05, 0x88, 0xec, 0x90, 0x9a, 0x8c, + 0x31, 0x16, 0x7d, 0x19, 0xcc, 0x63, 0x07, 0x7f, 0xa1, 0x8b, 0x2e, 0x97, 0xea, 0xdd, 0xed, 0x38, + 0xa3, 0x0f, 0xe8, 0x32, 0xa0, 0xba, 0x1b, 0x39, 0xeb, 0x1e, 0x99, 0x0b, 0x9a, 0x32, 0x1b, 0x57, + 0x1c, 0x4e, 0x9f, 0x15, 0xe3, 0x8c, 0xe6, 0xbb, 0x30, 0x70, 0xc6, 0x53, 0x6c, 0x96, 0x85, 0xc1, + 0x4e, 0xe7, 0x5a, 0xe8, 0x31, 0x2d, 0x61, 0xce, 0x32, 0xd1, 0x8e, 0x15, 0x86, 0xfd, 0x17, 0x45, + 0xb5, 0x94, 0x75, 0x40, 0xbd, 0x63, 0x04, 0xf6, 0x5a, 0x77, 0x1f, 0xd8, 0xab, 0xc3, 0x8e, 0xba, + 0x73, 0xcc, 0x13, 0x29, 0xa9, 0x85, 0x7b, 0x94, 0x92, 0xfa, 0xd3, 0x56, 0xa2, 0xbe, 0xdb, 0xf0, + 0xf9, 0x97, 0xf2, 0x0d, 0xe6, 0x9f, 0xe2, 0x21, 0x51, 0x29, 0xbd, 0x92, 0x8a, 0x84, 0x7b, 0x0a, + 0xca, 0x1b, 0x9e, 0xc3, 0xaa, 0x92, 0xb0, 0x85, 0x6a, 0x84, 0x6b, 0x5d, 0x14, 0xed, 0x58, 0x61, + 0x50, 0xa9, 0x6f, 0x10, 0x3d, 0x90, 0xd4, 0xfe, 0x2f, 0x45, 0x18, 0x36, 0x34, 0x7e, 0xa6, 0xf9, + 0x66, 0xdd, 0x67, 0xe6, 0x5b, 0xe1, 0x00, 0xe6, 0xdb, 0x4f, 0x41, 0xa5, 0x26, 0xb5, 0x51, 0x3e, + 0xf5, 0xea, 0xd3, 0x3a, 0x4e, 0x2b, 0x24, 0xd5, 0x84, 0x35, 0x4f, 0xb4, 0x90, 0x48, 0x7b, 0x4c, + 0xf8, 0x05, 0xb2, 0xf2, 0x12, 0x85, 0x46, 0xeb, 0x7e, 0x26, 0x7d, 0x8e, 0x5f, 0xda, 0xff, 0x1c, + 0xdf, 0xfe, 0xa6, 0xa5, 0x3e, 0xee, 0x31, 0xd4, 0xb7, 0xb9, 0x99, 0xac, 0x6f, 0x73, 0x21, 0x97, + 0x61, 0xee, 0x51, 0xd8, 0xe6, 0x2a, 0x0c, 0xcd, 0x05, 0xcd, 0xa6, 0xe3, 0xd7, 0xd1, 0xf7, 0xc3, + 0x50, 0x8d, 0xff, 0x14, 0x3e, 0x34, 0x76, 0x52, 0x2d, 0xa0, 0x58, 0xc2, 0xd0, 0x23, 0x30, 0xe0, + 0x84, 0x0d, 0xe9, 0x37, 0x63, 0x11, 0x65, 0x33, 0x61, 0x23, 0xc2, 0xac, 0xd5, 0xfe, 0x17, 0x03, + 0xc0, 0x02, 0x39, 0x9c, 0x90, 0xd4, 0xd7, 0x02, 0x56, 0x66, 0xf6, 0x48, 0xcf, 0x77, 0xf5, 0xa6, + 0xee, 0x7e, 0x3e, 0xe3, 0x35, 0xce, 0xf9, 0x8a, 0xc7, 0x7d, 0xce, 0x97, 0x7d, 0x74, 0x3b, 0x70, + 0x1f, 0x1d, 0xdd, 0xda, 0x9f, 0xb0, 0x00, 0xa9, 0xe8, 0x1f, 0x1d, 0x5b, 0x31, 0x0d, 0x15, 0x15, + 0x07, 0x24, 0x0c, 0x40, 0x2d, 0x22, 0x24, 0x00, 0x6b, 0x9c, 0x3e, 0x76, 0xf2, 0x8f, 0x4b, 0xf9, + 0x5d, 0x4c, 0x06, 0xf3, 0x33, 0xa9, 0x2f, 0xc4, 0xb9, 0xfd, 0xdb, 0x05, 0x78, 0x80, 0x9b, 0x0e, + 0xcb, 0x8e, 0xef, 0x34, 0x48, 0x93, 0xf6, 0xaa, 0xdf, 0x68, 0x99, 0x1a, 0xdd, 0x42, 0xba, 0x32, + 0xf4, 0xfe, 0xb0, 0x6b, 0x97, 0xaf, 0x39, 0xbe, 0xca, 0x16, 0x7d, 0x37, 0xc6, 0x8c, 0x38, 0x8a, + 0xa0, 0x2c, 0x2f, 0x73, 0x11, 0xb2, 0x38, 0x27, 0x46, 0x4a, 0x2c, 0x09, 0x2d, 0x4b, 0xb0, 0x62, + 0x44, 0x55, 0xa9, 0x17, 0xd4, 0xb6, 0x30, 0x69, 0x05, 0x69, 0x55, 0xba, 0x24, 0xda, 0xb1, 0xc2, + 0xb0, 0x9b, 0x30, 0x2e, 0xc7, 0xb0, 0x75, 0x85, 0x74, 0x30, 0xd9, 0xa0, 0xfa, 0xa7, 0x26, 0x9b, + 0x8c, 0xfb, 0x65, 0x94, 0xfe, 0x99, 0x33, 0x81, 0x38, 0x89, 0x2b, 0x2b, 0xcf, 0x16, 0xb2, 0x2b, + 0xcf, 0xda, 0xbf, 0x6d, 0x41, 0x5a, 0x01, 0x1a, 0x75, 0x36, 0xad, 0x3d, 0xeb, 0x6c, 0x1e, 0xa0, + 0x52, 0xe5, 0x4f, 0xc0, 0xb0, 0x13, 0x53, 0x0b, 0x87, 0x7b, 0x23, 0x8a, 0x77, 0x77, 0x8a, 0xb6, + 0x1c, 0xd4, 0xdd, 0x0d, 0x97, 0x79, 0x21, 0x4c, 0x72, 0xf6, 0xeb, 0x16, 0x54, 0xe6, 0xc3, 0xce, + 0xc1, 0x73, 0xa0, 0xba, 0x33, 0x9c, 0x0a, 0x07, 0xca, 0x70, 0x92, 0x39, 0x54, 0xc5, 0x5e, 0x39, + 0x54, 0xf6, 0x5f, 0x0d, 0xc0, 0xc9, 0xae, 0xa4, 0x3e, 0xf4, 0x3c, 0x8c, 0xa8, 0xaf, 0x24, 0x5d, + 0x90, 0x15, 0x33, 0x2a, 0x56, 0xc3, 0x70, 0x02, 0xb3, 0x8f, 0xa5, 0xba, 0x08, 0xa7, 0x42, 0xf2, + 0x6a, 0x9b, 0xb4, 0xc9, 0xcc, 0x46, 0x4c, 0xc2, 0x2a, 0xa9, 0x05, 0x7e, 0x9d, 0x17, 0xaa, 0x2d, + 0xce, 0x3e, 0x78, 0x7b, 0x77, 0xf2, 0x14, 0xee, 0x06, 0xe3, 0xac, 0x67, 0x50, 0x0b, 0x46, 0x3d, + 0xd3, 0x76, 0x16, 0x5b, 0xb6, 0xbb, 0x32, 0xbb, 0xd5, 0x6c, 0x4d, 0x34, 0xe3, 0x24, 0x83, 0xa4, + 0x01, 0x5e, 0xba, 0x47, 0x06, 0xf8, 0x87, 0xb5, 0x01, 0xce, 0x83, 0x62, 0xde, 0x9d, 0x73, 0x52, + 0x67, 0x3f, 0x16, 0xf8, 0x61, 0x6c, 0xea, 0x17, 0xa1, 0x2c, 0x03, 0x06, 0xfb, 0x0a, 0xb4, 0x33, + 0xe9, 0xf4, 0x90, 0xed, 0x4f, 0xc0, 0x9b, 0x2f, 0x84, 0xa1, 0x31, 0x98, 0x57, 0x83, 0x78, 0xc6, + 0xf3, 0x82, 0x5b, 0xd4, 0x5c, 0xb9, 0x16, 0x11, 0xe1, 0x13, 0xb3, 0xef, 0x14, 0x20, 0x63, 0x7b, + 0x49, 0xd7, 0xa4, 0xb6, 0x91, 0x12, 0x6b, 0xf2, 0x60, 0x76, 0x12, 0xda, 0xe1, 0x41, 0x95, 0xdc, + 0x1a, 0x78, 0x57, 0xde, 0xdb, 0x63, 0x1d, 0x67, 0xa9, 0x24, 0xa5, 0x8a, 0xb5, 0x3c, 0x0f, 0xa0, + 0x4d, 0x5b, 0x91, 0x47, 0xa4, 0x02, 0x25, 0xb4, 0x05, 0x8c, 0x0d, 0x2c, 0xf4, 0x1c, 0x0c, 0xbb, + 0x7e, 0x14, 0x3b, 0x9e, 0x77, 0xc9, 0xf5, 0x63, 0xe1, 0xf6, 0x55, 0x66, 0xcf, 0xa2, 0x06, 0x61, + 0x13, 0xef, 0xec, 0xdb, 0x8c, 0xef, 0x77, 0x90, 0xef, 0xbe, 0x09, 0x0f, 0x2d, 0xb8, 0xb1, 0xca, + 0x7e, 0x53, 0xf3, 0x8d, 0x5a, 0xae, 0x4a, 0x56, 0x59, 0x3d, 0xf3, 0x3d, 0x8d, 0xec, 0xb3, 0x42, + 0x32, 0x59, 0x2e, 0x9d, 0x7d, 0x66, 0x3f, 0x0f, 0xa7, 0x17, 0xdc, 0xf8, 0xa2, 0xeb, 0x91, 0x03, + 0x32, 0xb1, 0x7f, 0x6b, 0x10, 0x46, 0xcc, 0x4c, 0xef, 0x83, 0x88, 0xeb, 0x4f, 0x51, 0xe3, 0x54, + 0xbc, 0x9d, 0xab, 0x4e, 0x74, 0x6f, 0x1c, 0x3a, 0xed, 0x3c, 0x7b, 0xc4, 0x0c, 0xfb, 0x54, 0xf3, + 0xc4, 0x66, 0x07, 0xd0, 0x2d, 0x28, 0x6d, 0xb0, 0xec, 0xa8, 0x62, 0x1e, 0xb1, 0x38, 0x59, 0x23, + 0xaa, 0x97, 0x23, 0xcf, 0xaf, 0xe2, 0xfc, 0xa8, 0x4d, 0x11, 0x26, 0x93, 0x72, 0x8d, 0x98, 0x75, + 0xa1, 0xac, 0x14, 0x46, 0x2f, 0x95, 0x50, 0xba, 0x0b, 0x95, 0x90, 0x10, 0xd0, 0x83, 0xf7, 0x48, + 0x40, 0xb3, 0x4c, 0xb7, 0x78, 0x93, 0x59, 0xbc, 0x22, 0xc9, 0x66, 0x88, 0x0d, 0x82, 0x91, 0xe9, + 0x96, 0x00, 0xe3, 0x34, 0x3e, 0xfa, 0x80, 0x12, 0xf1, 0xe5, 0x3c, 0x3c, 0xe6, 0xe6, 0x8c, 0x3e, + 0x6a, 0xe9, 0xfe, 0x89, 0x02, 0x8c, 0x2d, 0xf8, 0xed, 0xd5, 0x85, 0xd5, 0xf6, 0xba, 0xe7, 0xd6, + 0xae, 0x90, 0x0e, 0x15, 0xe1, 0x5b, 0xa4, 0xb3, 0x38, 0x2f, 0x56, 0x90, 0x9a, 0x33, 0x57, 0x68, + 0x23, 0xe6, 0x30, 0x2a, 0x8c, 0x36, 0x5c, 0xbf, 0x41, 0xc2, 0x56, 0xe8, 0x0a, 0x67, 0xb6, 0x21, + 0x8c, 0x2e, 0x6a, 0x10, 0x36, 0xf1, 0x28, 0xed, 0xe0, 0x96, 0x4f, 0xc2, 0xb4, 0xe9, 0xbf, 0x42, + 0x1b, 0x31, 0x87, 0x51, 0xa4, 0x38, 0x6c, 0x0b, 0x5f, 0x91, 0x81, 0xb4, 0x46, 0x1b, 0x31, 0x87, + 0xd1, 0x95, 0x1e, 0xb5, 0xd7, 0x59, 0xa8, 0x53, 0x2a, 0xa3, 0xa7, 0xca, 0x9b, 0xb1, 0x84, 0x53, + 0xd4, 0x2d, 0xd2, 0x99, 0x77, 0x62, 0x27, 0x9d, 0xf6, 0x78, 0x85, 0x37, 0x63, 0x09, 0x67, 0xa5, + 0x74, 0x93, 0xc3, 0xf1, 0x5d, 0x57, 0x4a, 0x37, 0xd9, 0xfd, 0x1e, 0x1e, 0x87, 0xbf, 0x57, 0x80, + 0x11, 0x33, 0x40, 0x11, 0x35, 0x52, 0x66, 0xfa, 0x4a, 0x57, 0x25, 0xf6, 0x1f, 0xcb, 0xba, 0xa5, + 0xb4, 0xe1, 0xc6, 0x41, 0x2b, 0x7a, 0x9a, 0xf8, 0x0d, 0xd7, 0x27, 0x2c, 0x56, 0x83, 0x07, 0x36, + 0x26, 0xa2, 0x1f, 0xe7, 0x82, 0x3a, 0xb9, 0x1b, 0x3b, 0xff, 0x5e, 0xdc, 0xe4, 0x72, 0x03, 0x4e, + 0x76, 0xe5, 0xd7, 0xf6, 0x61, 0xf6, 0xec, 0x5b, 0xff, 0xc0, 0xc6, 0x30, 0x4c, 0x09, 0xcb, 0x12, + 0x72, 0x73, 0x70, 0x92, 0x2f, 0x5e, 0xca, 0x89, 0xa5, 0x4b, 0xaa, 0x9c, 0x69, 0x76, 0x5a, 0x73, + 0x3d, 0x0d, 0xc4, 0xdd, 0xf8, 0xf6, 0x27, 0x2d, 0x18, 0x4d, 0xa4, 0x3c, 0xe7, 0x64, 0xa0, 0xb1, + 0xd5, 0x1d, 0xb0, 0x18, 0x5d, 0x96, 0x33, 0x51, 0x64, 0x0a, 0x5c, 0xaf, 0x6e, 0x0d, 0xc2, 0x26, + 0x9e, 0xfd, 0xd9, 0x02, 0x94, 0x65, 0x48, 0x51, 0x1f, 0x5d, 0xf9, 0xb8, 0x05, 0xa3, 0xea, 0x84, + 0x8c, 0xb9, 0x34, 0x0b, 0x79, 0x64, 0x60, 0xd1, 0x1e, 0x28, 0xa7, 0x88, 0xbf, 0x11, 0xe8, 0xdd, + 0x02, 0x36, 0x99, 0xe1, 0x24, 0x6f, 0x74, 0x1d, 0x20, 0xea, 0x44, 0x31, 0x69, 0x1a, 0xce, 0x55, + 0xdb, 0x98, 0x65, 0x53, 0xb5, 0x20, 0x24, 0x74, 0x4e, 0x5d, 0x0d, 0xea, 0xa4, 0xaa, 0x30, 0xb5, + 0xd9, 0xa6, 0xdb, 0xb0, 0x41, 0xc9, 0xfe, 0xd5, 0x02, 0x9c, 0x48, 0x77, 0x09, 0xbd, 0x1b, 0x46, + 0x24, 0x77, 0x63, 0x13, 0x2e, 0x03, 0xa2, 0x46, 0xb0, 0x01, 0xbb, 0xb3, 0x3b, 0x39, 0xd9, 0x7d, + 0xcb, 0xee, 0x94, 0x89, 0x82, 0x13, 0xc4, 0xf8, 0x31, 0xa5, 0x38, 0x4f, 0x9f, 0xed, 0xcc, 0xb4, + 0x5a, 0xe2, 0xac, 0xd1, 0x38, 0xa6, 0x34, 0xa1, 0x38, 0x85, 0x8d, 0x56, 0xe1, 0xb4, 0xd1, 0x72, + 0x95, 0xb8, 0x8d, 0xcd, 0xf5, 0x20, 0x94, 0xbb, 0xbe, 0x47, 0x74, 0xf8, 0x65, 0x37, 0x0e, 0xce, + 0x7c, 0x92, 0x5a, 0x18, 0x35, 0xa7, 0xe5, 0xd4, 0xdc, 0xb8, 0x23, 0xbc, 0xc5, 0x4a, 0x1e, 0xce, + 0x89, 0x76, 0xac, 0x30, 0xec, 0x5f, 0x19, 0x80, 0x13, 0x3c, 0xde, 0x90, 0xa8, 0x70, 0x5a, 0xf4, + 0x6e, 0xa8, 0x44, 0xb1, 0x13, 0xf2, 0x2d, 0xbf, 0x75, 0x60, 0x19, 0xa0, 0x13, 0x9e, 0x25, 0x11, + 0xac, 0xe9, 0xa1, 0x97, 0x58, 0xb5, 0x28, 0x37, 0xda, 0x64, 0xd4, 0x0b, 0x77, 0xe7, 0x50, 0xb8, + 0xa8, 0x28, 0x60, 0x83, 0x1a, 0xfa, 0x51, 0x28, 0xb5, 0x36, 0x9d, 0x48, 0x7a, 0xbb, 0x9e, 0x90, + 0x0b, 0x6e, 0x95, 0x36, 0xde, 0xd9, 0x9d, 0x3c, 0x93, 0x7e, 0x55, 0x06, 0xc0, 0xfc, 0x21, 0x53, + 0x5c, 0x0e, 0xec, 0x7f, 0xa3, 0x49, 0x3d, 0xec, 0x54, 0x2f, 0xcd, 0xa4, 0xef, 0xc0, 0x98, 0x67, + 0xad, 0x58, 0x40, 0xe9, 0xe2, 0xde, 0xe4, 0x2c, 0xeb, 0x14, 0x79, 0x30, 0xa9, 0xba, 0x2f, 0x69, + 0x10, 0x36, 0xf1, 0xd0, 0x27, 0xba, 0xa3, 0x51, 0x87, 0x8e, 0x20, 0x55, 0xa1, 0xdf, 0x38, 0xd4, + 0x0b, 0x50, 0x11, 0x5d, 0x5d, 0x0b, 0xd0, 0xf3, 0x30, 0xc2, 0x9d, 0x29, 0xb3, 0xa1, 0xe3, 0xd7, + 0x36, 0xd3, 0x2e, 0x90, 0x35, 0x03, 0x86, 0x13, 0x98, 0xf6, 0x32, 0x0c, 0xf4, 0x29, 0xad, 0xfa, + 0xda, 0xd9, 0xbe, 0x08, 0x65, 0x4a, 0x4e, 0x6e, 0x5f, 0xf2, 0x20, 0x19, 0x40, 0x59, 0xde, 0x8f, + 0x87, 0x6c, 0x28, 0xba, 0x8e, 0x8c, 0x3a, 0x50, 0x4b, 0x68, 0x31, 0x8a, 0xda, 0x6c, 0xda, 0x51, + 0x20, 0x7a, 0x1c, 0x8a, 0x64, 0xa7, 0x95, 0x0e, 0x2f, 0xb8, 0xb0, 0xd3, 0x72, 0x43, 0x12, 0x51, + 0x24, 0xb2, 0xd3, 0x42, 0x67, 0xa1, 0xe0, 0xd6, 0xc5, 0x8c, 0x04, 0x81, 0x53, 0x58, 0x9c, 0xc7, + 0x05, 0xb7, 0x6e, 0xef, 0x40, 0x45, 0x5d, 0xc8, 0x87, 0xb6, 0xa4, 0x6d, 0x62, 0xe5, 0x11, 0x6f, + 0x2a, 0xe9, 0xf6, 0xb0, 0x4a, 0xda, 0x00, 0x3a, 0x93, 0x3e, 0x2f, 0x5d, 0x76, 0x0e, 0x06, 0x6a, + 0x81, 0xa8, 0x81, 0x52, 0xd6, 0x64, 0x98, 0x51, 0xc2, 0x20, 0xf6, 0x0d, 0x18, 0xbb, 0xe2, 0x07, + 0xb7, 0xd8, 0xbd, 0x39, 0xac, 0x4c, 0x2c, 0x25, 0xbc, 0x41, 0x7f, 0xa4, 0x4d, 0x60, 0x06, 0xc5, + 0x1c, 0xa6, 0x0a, 0x58, 0x16, 0x7a, 0x15, 0xb0, 0xb4, 0x3f, 0x68, 0xc1, 0x88, 0x4a, 0xc9, 0x5d, + 0xd8, 0xde, 0xa2, 0x74, 0x1b, 0x61, 0xd0, 0x6e, 0xa5, 0xe9, 0xb2, 0xbb, 0x3f, 0x31, 0x87, 0x99, + 0xb9, 0xea, 0x85, 0x7d, 0x72, 0xd5, 0xcf, 0xc1, 0xc0, 0x96, 0xeb, 0xd7, 0xd3, 0x2e, 0xc3, 0x2b, + 0xae, 0x5f, 0xc7, 0x0c, 0x62, 0xff, 0x6b, 0x0b, 0x4e, 0xa8, 0x2e, 0x48, 0xe3, 0xe3, 0x79, 0x18, + 0x59, 0x6f, 0xbb, 0x5e, 0x5d, 0xd6, 0xbf, 0x4d, 0x2d, 0x97, 0x59, 0x03, 0x86, 0x13, 0x98, 0xe8, + 0x3c, 0xc0, 0xba, 0xeb, 0x3b, 0x61, 0x67, 0x55, 0x5b, 0x3b, 0x4a, 0x01, 0xce, 0x2a, 0x08, 0x36, + 0xb0, 0x28, 0xb7, 0x88, 0xc4, 0x3a, 0x1c, 0x9e, 0x7f, 0x08, 0xc5, 0xad, 0x6a, 0xc0, 0x70, 0x02, + 0xd3, 0xfe, 0x74, 0x11, 0xc6, 0x92, 0x29, 0xcd, 0x7d, 0x38, 0x1e, 0x1e, 0x87, 0x12, 0xcb, 0x72, + 0x4e, 0x4f, 0x0a, 0x5e, 0x6c, 0x96, 0xc3, 0x50, 0x04, 0x83, 0x5c, 0x0c, 0xe4, 0x73, 0xf3, 0xa2, + 0xea, 0xa4, 0xf2, 0x50, 0xb2, 0x78, 0x5e, 0xe1, 0xf0, 0x15, 0xac, 0xd0, 0x47, 0x2c, 0x18, 0x0a, + 0x5a, 0x66, 0xc9, 0xc4, 0x77, 0xe5, 0x99, 0xee, 0x2d, 0x72, 0x40, 0xc5, 0x5e, 0x51, 0x4d, 0x1a, + 0xf9, 0x21, 0x25, 0xeb, 0xb3, 0x3f, 0x02, 0x23, 0x26, 0xe6, 0x7e, 0xdb, 0xc5, 0xb2, 0xb9, 0x5d, + 0xfc, 0xb8, 0x39, 0x9d, 0x44, 0x42, 0x7b, 0x1f, 0x0b, 0xf5, 0x1a, 0x94, 0x6a, 0x2a, 0xe8, 0xe9, + 0xae, 0xea, 0xad, 0xab, 0x82, 0x4f, 0xec, 0x40, 0x99, 0x53, 0xb3, 0xbf, 0x69, 0x19, 0xf3, 0x03, + 0x93, 0x68, 0xb1, 0x8e, 0x42, 0x28, 0x36, 0xb6, 0xb7, 0x84, 0x81, 0x70, 0x39, 0xa7, 0xe1, 0x5d, + 0xd8, 0xde, 0xd2, 0xf3, 0xd5, 0x6c, 0xc5, 0x94, 0x59, 0x1f, 0x6e, 0xf4, 0x44, 0xdd, 0x83, 0xe2, + 0xfe, 0x75, 0x0f, 0xec, 0xd7, 0x0b, 0x70, 0xb2, 0x6b, 0x52, 0xa1, 0xd7, 0xa0, 0x14, 0xd2, 0xb7, + 0x14, 0xaf, 0xb7, 0x94, 0x5b, 0xa5, 0x82, 0x68, 0xb1, 0xae, 0x15, 0x6f, 0xb2, 0x1d, 0x73, 0x96, + 0xe8, 0x32, 0x20, 0x1d, 0x9a, 0xa7, 0x7c, 0xf8, 0xfc, 0x95, 0x55, 0xfc, 0xce, 0x4c, 0x17, 0x06, + 0xce, 0x78, 0x0a, 0xbd, 0x90, 0x3e, 0x0a, 0x28, 0x26, 0xcf, 0xa0, 0xf6, 0xf2, 0xea, 0xdb, 0xbf, + 0x59, 0x80, 0xd1, 0x44, 0x05, 0x4b, 0xe4, 0x41, 0x99, 0x78, 0xec, 0x80, 0x50, 0xaa, 0xa9, 0xc3, + 0xde, 0x47, 0xa1, 0x54, 0xeb, 0x05, 0x41, 0x17, 0x2b, 0x0e, 0xf7, 0x47, 0x58, 0xcf, 0xf3, 0x30, + 0x22, 0x3b, 0xf4, 0x2e, 0xa7, 0xe9, 0x89, 0x01, 0x54, 0x73, 0xf4, 0x82, 0x01, 0xc3, 0x09, 0x4c, + 0xfb, 0x77, 0x8a, 0x30, 0xc1, 0x4f, 0x54, 0xeb, 0x6a, 0xe6, 0x2d, 0x4b, 0x4f, 0xc4, 0xcf, 0xeb, + 0x3a, 0xb3, 0x56, 0x1e, 0x97, 0x2e, 0xf7, 0x62, 0xd4, 0x57, 0x34, 0xea, 0x17, 0x52, 0xd1, 0xa8, + 0x7c, 0x73, 0xd8, 0x38, 0xa2, 0x1e, 0x7d, 0x77, 0x85, 0xa7, 0xfe, 0x93, 0x02, 0x8c, 0xa7, 0xee, + 0xd6, 0x42, 0x9f, 0x4e, 0x5e, 0xc7, 0x60, 0xe5, 0x71, 0xda, 0xb4, 0xe7, 0x75, 0x4b, 0x07, 0xbb, + 0x94, 0xe1, 0x1e, 0x2d, 0x15, 0xfb, 0x1b, 0x05, 0x18, 0x4b, 0x5e, 0x0a, 0x76, 0x1f, 0x8e, 0xd4, + 0x5b, 0xa1, 0xc2, 0xee, 0xbd, 0x61, 0x77, 0xd9, 0xf3, 0xc3, 0x2a, 0x7e, 0xc5, 0x88, 0x6c, 0xc4, + 0x1a, 0x7e, 0x5f, 0xdc, 0x75, 0x61, 0xff, 0x33, 0x0b, 0xce, 0xf0, 0xb7, 0x4c, 0xcf, 0xc3, 0xbf, + 0x93, 0x35, 0xba, 0x2f, 0xe7, 0xdb, 0xc1, 0x54, 0x7d, 0xe4, 0xfd, 0xc6, 0x97, 0x5d, 0x3d, 0x2d, + 0x7a, 0x9b, 0x9c, 0x0a, 0xf7, 0x61, 0x67, 0x0f, 0x34, 0x19, 0xec, 0x6f, 0x14, 0x41, 0xdf, 0xb6, + 0x8d, 0x5c, 0x91, 0x2f, 0x9f, 0x4b, 0x9d, 0xe8, 0x6a, 0xc7, 0xaf, 0xe9, 0x7b, 0xbd, 0xcb, 0xa9, + 0x74, 0xf9, 0x9f, 0xb5, 0x60, 0xd8, 0xf5, 0xdd, 0xd8, 0x75, 0x98, 0xb3, 0x27, 0x9f, 0x2b, 0x73, + 0x15, 0xbb, 0x45, 0x4e, 0x39, 0x08, 0xcd, 0x13, 0x4e, 0xc5, 0x0c, 0x9b, 0x9c, 0xd1, 0x7b, 0x45, + 0xc2, 0x48, 0x31, 0xb7, 0xa2, 0x13, 0xe5, 0x54, 0x96, 0x48, 0x8b, 0x1a, 0x5e, 0x71, 0x98, 0x53, + 0xad, 0x16, 0x4c, 0x49, 0xa9, 0x2b, 0x07, 0x94, 0x69, 0xcb, 0x9a, 0x31, 0x67, 0x64, 0x47, 0x80, + 0xba, 0xc7, 0xe2, 0x80, 0xc1, 0xf8, 0xd3, 0x50, 0x71, 0xda, 0x71, 0xd0, 0xa4, 0xc3, 0x24, 0x0e, + 0x61, 0x75, 0xba, 0x81, 0x04, 0x60, 0x8d, 0x63, 0x7f, 0xba, 0x04, 0xa9, 0x04, 0x76, 0xb4, 0x63, + 0xde, 0x14, 0x6f, 0xe5, 0x7b, 0x53, 0xbc, 0xea, 0x4c, 0xd6, 0x6d, 0xf1, 0xa8, 0x21, 0xfd, 0x66, + 0xdc, 0xc6, 0x7c, 0x31, 0xed, 0x37, 0xfb, 0xf1, 0xfe, 0xce, 0x23, 0xe8, 0x5c, 0x9d, 0xe6, 0xf5, + 0xbf, 0xa6, 0xf6, 0x75, 0xb1, 0xed, 0x77, 0x69, 0xf0, 0x87, 0xc4, 0x05, 0x3f, 0x98, 0x44, 0x6d, + 0x2f, 0x16, 0xb3, 0xe1, 0xc5, 0x1c, 0x57, 0x19, 0x27, 0xac, 0xab, 0xc0, 0xf0, 0xff, 0xd8, 0x60, + 0x9a, 0x74, 0x84, 0x0e, 0x1e, 0xa9, 0x23, 0x74, 0x28, 0x57, 0x47, 0xe8, 0x79, 0x00, 0x36, 0xb7, + 0x79, 0xd0, 0x70, 0x99, 0xf9, 0xa7, 0x94, 0x28, 0xc4, 0x0a, 0x82, 0x0d, 0x2c, 0xfb, 0x07, 0x21, + 0x59, 0xc6, 0x08, 0x4d, 0xca, 0xaa, 0x49, 0xfc, 0xac, 0x84, 0xe5, 0x6b, 0x25, 0x0a, 0x1c, 0xfd, + 0xba, 0x05, 0x66, 0xad, 0x25, 0xf4, 0x2a, 0x2f, 0xea, 0x64, 0xe5, 0x71, 0xa6, 0x6e, 0xd0, 0x9d, + 0x5a, 0x76, 0x5a, 0xa9, 0xe0, 0x0e, 0x59, 0xd9, 0xe9, 0xec, 0xdb, 0xa0, 0x2c, 0xa1, 0x07, 0x32, + 0xea, 0x3e, 0x00, 0xa7, 0x64, 0xee, 0xb7, 0xf4, 0xee, 0x8b, 0xf3, 0xd8, 0xfd, 0x9d, 0x46, 0xd2, + 0x13, 0x54, 0xe8, 0xe5, 0x09, 0x52, 0xbb, 0xd4, 0x62, 0xcf, 0xf2, 0xc7, 0xbf, 0x61, 0xc1, 0xb9, + 0x74, 0x07, 0xa2, 0xe5, 0xc0, 0x77, 0xe3, 0x20, 0xac, 0x92, 0x38, 0x76, 0xfd, 0x06, 0xab, 0x65, + 0x79, 0xcb, 0x09, 0xe5, 0x7d, 0x26, 0x4c, 0x50, 0xde, 0x70, 0x42, 0x1f, 0xb3, 0x56, 0xd4, 0x81, + 0x41, 0x1e, 0x59, 0x2a, 0xac, 0xf5, 0x43, 0xae, 0x8d, 0x8c, 0xe1, 0xd0, 0xdb, 0x05, 0x1e, 0xd5, + 0x8a, 0x05, 0x43, 0xfb, 0xdb, 0x16, 0xa0, 0x95, 0x6d, 0x12, 0x86, 0x6e, 0xdd, 0x88, 0x85, 0x65, + 0x17, 0xe5, 0x19, 0x17, 0xe2, 0x99, 0x95, 0x09, 0x52, 0x17, 0xe5, 0x19, 0xff, 0xb2, 0x2f, 0xca, + 0x2b, 0x1c, 0xec, 0xa2, 0x3c, 0xb4, 0x02, 0x67, 0x9a, 0x7c, 0xbb, 0xc1, 0x2f, 0x9f, 0xe2, 0x7b, + 0x0f, 0x95, 0x44, 0xfb, 0xd0, 0xed, 0xdd, 0xc9, 0x33, 0xcb, 0x59, 0x08, 0x38, 0xfb, 0x39, 0xfb, + 0x6d, 0x80, 0x78, 0x08, 0xec, 0x5c, 0x56, 0x14, 0x5f, 0x4f, 0xf7, 0x8b, 0xfd, 0xf9, 0x12, 0x8c, + 0xa7, 0xaa, 0xdd, 0xd3, 0xad, 0x5e, 0x77, 0xd8, 0xe0, 0xa1, 0xf5, 0x77, 0x77, 0xf7, 0xfa, 0x0a, + 0x44, 0xf4, 0xa1, 0xe4, 0xfa, 0xad, 0x76, 0x9c, 0x4f, 0x0e, 0x3f, 0xef, 0xc4, 0x22, 0x25, 0x68, + 0x38, 0x9a, 0xe9, 0x5f, 0xcc, 0xd9, 0xe4, 0x19, 0xd6, 0x98, 0x30, 0xc6, 0x07, 0xee, 0x91, 0x3b, + 0xe0, 0x43, 0x3a, 0xc8, 0xb0, 0x94, 0x87, 0x63, 0x31, 0x35, 0x59, 0x8e, 0x3a, 0x08, 0xe5, 0xab, + 0x05, 0x18, 0x36, 0x3e, 0x1a, 0xfa, 0xe5, 0x64, 0x25, 0x42, 0x2b, 0xbf, 0x57, 0x62, 0xf4, 0xa7, + 0x74, 0xad, 0x41, 0xfe, 0x4a, 0x4f, 0x74, 0x17, 0x21, 0xbc, 0xb3, 0x3b, 0x79, 0x22, 0x55, 0x66, + 0x30, 0x51, 0x98, 0xf0, 0xec, 0xfb, 0x61, 0x3c, 0x45, 0x26, 0xe3, 0x95, 0xd7, 0xcc, 0x57, 0x3e, + 0xb4, 0x5b, 0xca, 0x1c, 0xb2, 0xaf, 0xd0, 0x21, 0x13, 0xa9, 0xc3, 0x81, 0x47, 0xfa, 0xf0, 0xc1, + 0xa6, 0x2a, 0x04, 0x14, 0xfa, 0xac, 0x10, 0xf0, 0x24, 0x94, 0x5b, 0x81, 0xe7, 0xd6, 0x5c, 0x55, + 0x18, 0x98, 0xd5, 0x24, 0x58, 0x15, 0x6d, 0x58, 0x41, 0xd1, 0x2d, 0xa8, 0xdc, 0xbc, 0x15, 0xf3, + 0x73, 0x23, 0xe1, 0xdf, 0xce, 0xeb, 0xb8, 0x48, 0x19, 0x2d, 0xea, 0x60, 0x0a, 0x6b, 0x5e, 0xc8, + 0x86, 0x41, 0xa6, 0x04, 0x65, 0x1a, 0x11, 0xf3, 0xbd, 0x33, 0xed, 0x18, 0x61, 0x01, 0xb1, 0xbf, + 0x54, 0x81, 0xd3, 0x59, 0x57, 0x8e, 0xa0, 0xf7, 0xc1, 0x20, 0xef, 0x63, 0x3e, 0xb7, 0x5a, 0x65, + 0xf1, 0x58, 0x60, 0x04, 0x45, 0xb7, 0xd8, 0x6f, 0x2c, 0x78, 0x0a, 0xee, 0x9e, 0xb3, 0x2e, 0x66, + 0xc8, 0xd1, 0x70, 0x5f, 0x72, 0x34, 0xf7, 0x25, 0x87, 0x73, 0xf7, 0x9c, 0x75, 0xb4, 0x03, 0xa5, + 0x86, 0x1b, 0x13, 0x47, 0x38, 0x11, 0x6e, 0x1c, 0x09, 0x73, 0xe2, 0x70, 0x2b, 0x8d, 0xfd, 0xc4, + 0x9c, 0x21, 0xfa, 0xa2, 0x05, 0xe3, 0xeb, 0xc9, 0xd2, 0x24, 0x42, 0x78, 0x3a, 0x47, 0x70, 0xad, + 0x4c, 0x92, 0x11, 0xbf, 0x29, 0x32, 0xd5, 0x88, 0xd3, 0xdd, 0x41, 0x1f, 0xb6, 0x60, 0x68, 0xc3, + 0xf5, 0x8c, 0xba, 0xfd, 0x47, 0xf0, 0x71, 0x2e, 0x32, 0x06, 0x7a, 0xc7, 0xc1, 0xff, 0x47, 0x58, + 0x72, 0xee, 0xa5, 0xa9, 0x06, 0x0f, 0xab, 0xa9, 0x86, 0xee, 0x91, 0xa6, 0xfa, 0x98, 0x05, 0x15, + 0x35, 0xd2, 0xa2, 0xc4, 0xc3, 0xbb, 0x8f, 0xf0, 0x93, 0x73, 0xcf, 0x89, 0xfa, 0x8b, 0x35, 0x73, + 0xf4, 0x19, 0x0b, 0x86, 0x9d, 0xd7, 0xda, 0x21, 0xa9, 0x93, 0xed, 0xa0, 0x15, 0x89, 0xc2, 0x8b, + 0x2f, 0xe7, 0xdf, 0x99, 0x19, 0xca, 0x64, 0x9e, 0x6c, 0xaf, 0xb4, 0x22, 0x91, 0xe2, 0xa8, 0x1b, + 0xb0, 0xd9, 0x05, 0x7b, 0xb7, 0x00, 0x93, 0xfb, 0x50, 0x40, 0xcf, 0xc3, 0x48, 0x10, 0x36, 0x1c, + 0xdf, 0x7d, 0xcd, 0xac, 0x35, 0xa4, 0xac, 0xac, 0x15, 0x03, 0x86, 0x13, 0x98, 0x66, 0x11, 0x8a, + 0xc2, 0x3e, 0x45, 0x28, 0xce, 0xc1, 0x40, 0x48, 0x5a, 0x41, 0x7a, 0xb3, 0xc0, 0xd2, 0x8b, 0x18, + 0x04, 0x3d, 0x0a, 0x45, 0xa7, 0xe5, 0x8a, 0xa0, 0x14, 0xb5, 0x07, 0x9a, 0x59, 0x5d, 0xc4, 0xb4, + 0x3d, 0x51, 0x13, 0xa7, 0x74, 0x2c, 0x35, 0x71, 0xa8, 0x1a, 0x10, 0x67, 0x17, 0x83, 0x5a, 0x0d, + 0x24, 0xcf, 0x14, 0xec, 0xd7, 0x8b, 0xf0, 0xe8, 0x9e, 0xf3, 0x45, 0x47, 0xa8, 0x5a, 0x7b, 0x44, + 0xa8, 0xca, 0xe1, 0x29, 0xec, 0x37, 0x3c, 0xc5, 0x1e, 0xc3, 0xf3, 0x61, 0xba, 0x0c, 0x64, 0x8d, + 0xa6, 0x7c, 0x2e, 0x0a, 0xee, 0x55, 0xf2, 0x49, 0xac, 0x00, 0x09, 0xc5, 0x9a, 0x2f, 0xdd, 0x03, + 0x24, 0x0a, 0x30, 0x94, 0xf2, 0x50, 0x03, 0x3d, 0xeb, 0x24, 0xf1, 0xb9, 0xdf, 0xab, 0xaa, 0x83, + 0xfd, 0x6f, 0x06, 0xe0, 0xf1, 0x3e, 0xa4, 0xb7, 0x39, 0x8b, 0xad, 0x3e, 0x67, 0xf1, 0x77, 0xf9, + 0x67, 0xfa, 0x68, 0xe6, 0x67, 0xc2, 0xf9, 0x7f, 0xa6, 0xbd, 0xbf, 0x10, 0x7a, 0x0a, 0xca, 0xae, + 0x1f, 0x91, 0x5a, 0x3b, 0xe4, 0xd1, 0xfa, 0x46, 0xee, 0xe1, 0xa2, 0x68, 0xc7, 0x0a, 0x83, 0xee, + 0xe9, 0x6a, 0x0e, 0x5d, 0xfe, 0x43, 0x39, 0x25, 0xdc, 0x9b, 0x69, 0x8c, 0xdc, 0xa4, 0x98, 0x9b, + 0xa1, 0x12, 0x80, 0xb3, 0xb1, 0xff, 0xae, 0x05, 0x67, 0x7b, 0xab, 0x58, 0xf4, 0x0c, 0x0c, 0xaf, + 0xb3, 0x90, 0x2f, 0x76, 0x45, 0xbc, 0x9c, 0x3a, 0xec, 0x7d, 0x75, 0x33, 0x36, 0x71, 0xd0, 0x1c, + 0x9c, 0x34, 0x63, 0xc5, 0x96, 0x8d, 0xa8, 0x12, 0xe6, 0x04, 0x58, 0x4b, 0x03, 0x71, 0x37, 0xbe, + 0xfd, 0x9d, 0x62, 0x76, 0xb7, 0xb8, 0x29, 0x76, 0x90, 0xd9, 0x2c, 0xe6, 0x6a, 0xa1, 0x0f, 0x89, + 0x5b, 0x3c, 0x6e, 0x89, 0x3b, 0xd0, 0x4b, 0xe2, 0xa2, 0x79, 0x38, 0x61, 0xdc, 0xe1, 0xc7, 0x4b, + 0x30, 0xf0, 0xf8, 0x44, 0x55, 0x3f, 0x69, 0x35, 0x05, 0xc7, 0x5d, 0x4f, 0xdc, 0xe7, 0x53, 0xef, + 0x57, 0x0a, 0xf0, 0x50, 0x4f, 0xeb, 0xf7, 0x98, 0x34, 0x8a, 0xf9, 0xf9, 0x07, 0x8e, 0xe7, 0xf3, + 0x9b, 0x1f, 0xa5, 0xb4, 0xdf, 0x47, 0xb1, 0xff, 0xa8, 0xd0, 0x73, 0x21, 0xd0, 0x9d, 0xd0, 0xf7, + 0xec, 0x28, 0xbd, 0x00, 0xa3, 0x4e, 0xab, 0xc5, 0xf1, 0x58, 0xac, 0x77, 0xaa, 0x5e, 0xdb, 0x8c, + 0x09, 0xc4, 0x49, 0xdc, 0xbe, 0x6c, 0x9a, 0x3f, 0xb1, 0xa0, 0x82, 0xc9, 0x06, 0x97, 0x46, 0xe8, + 0xa6, 0x18, 0x22, 0x2b, 0x8f, 0x8a, 0xd9, 0x74, 0x60, 0x23, 0x97, 0x55, 0x92, 0xce, 0x1a, 0xec, + 0xc3, 0x66, 0x3c, 0xab, 0x5b, 0xfd, 0x8a, 0xbd, 0x6f, 0xf5, 0xb3, 0xbf, 0x35, 0x44, 0x5f, 0xaf, + 0x15, 0xcc, 0x85, 0xa4, 0x1e, 0xd1, 0xef, 0xdb, 0x0e, 0x3d, 0x31, 0x49, 0xd4, 0xf7, 0xbd, 0x86, + 0x97, 0x30, 0x6d, 0x4f, 0x1c, 0x90, 0x15, 0x0e, 0x54, 0xad, 0xaa, 0xb8, 0x6f, 0xb5, 0xaa, 0x17, + 0x60, 0x34, 0x8a, 0x36, 0x57, 0x43, 0x77, 0xdb, 0x89, 0xc9, 0x15, 0xd2, 0x11, 0xb6, 0xaf, 0xae, + 0xdc, 0x52, 0xbd, 0xa4, 0x81, 0x38, 0x89, 0x8b, 0x16, 0xe0, 0xa4, 0xae, 0x19, 0x45, 0xc2, 0x98, + 0x65, 0x23, 0xf1, 0x99, 0xa0, 0xca, 0x34, 0xe8, 0x2a, 0x53, 0x02, 0x01, 0x77, 0x3f, 0x43, 0xe5, + 0x69, 0xa2, 0x91, 0x76, 0x64, 0x30, 0x29, 0x4f, 0x13, 0x74, 0x68, 0x5f, 0xba, 0x9e, 0x40, 0xcb, + 0x70, 0x8a, 0x4f, 0x8c, 0x99, 0x56, 0xcb, 0x78, 0xa3, 0xa1, 0x64, 0xa5, 0xe2, 0x85, 0x6e, 0x14, + 0x9c, 0xf5, 0x1c, 0x7a, 0x0e, 0x86, 0x55, 0xf3, 0xe2, 0xbc, 0x38, 0xdb, 0x51, 0xbe, 0x25, 0x45, + 0x66, 0xb1, 0x8e, 0x4d, 0x3c, 0xf4, 0x2e, 0x78, 0x50, 0xff, 0xe5, 0x29, 0xab, 0xfc, 0xc0, 0x73, + 0x5e, 0x94, 0xe3, 0x53, 0x37, 0xc4, 0x2d, 0x64, 0xa2, 0xd5, 0x71, 0xaf, 0xe7, 0xd1, 0x3a, 0x9c, + 0x55, 0xa0, 0x0b, 0x7e, 0xcc, 0xf2, 0xcf, 0x22, 0x32, 0xeb, 0x44, 0xe4, 0x5a, 0xe8, 0xb1, 0x02, + 0x7e, 0x15, 0x7d, 0xcd, 0xf8, 0x82, 0x1b, 0x5f, 0xca, 0xc2, 0xc4, 0x4b, 0x78, 0x0f, 0x2a, 0x68, + 0x1a, 0x2a, 0xc4, 0x77, 0xd6, 0x3d, 0xb2, 0x32, 0xb7, 0xc8, 0xca, 0xfa, 0x19, 0xe7, 0xab, 0x17, + 0x24, 0x00, 0x6b, 0x1c, 0x15, 0x31, 0x3c, 0xd2, 0xf3, 0xca, 0xfb, 0x55, 0x38, 0xdd, 0xa8, 0xb5, + 0xa8, 0x45, 0xe8, 0xd6, 0xc8, 0x4c, 0x8d, 0x85, 0x39, 0xd2, 0x0f, 0xc3, 0x4b, 0x48, 0xab, 0xd4, + 0x8b, 0x85, 0xb9, 0xd5, 0x2e, 0x1c, 0x9c, 0xf9, 0x24, 0x0b, 0x87, 0x0d, 0x83, 0x9d, 0xce, 0xc4, + 0xa9, 0x54, 0x38, 0x2c, 0x6d, 0xc4, 0x1c, 0x86, 0x2e, 0x03, 0x62, 0x79, 0x3c, 0x97, 0xe2, 0xb8, + 0xa5, 0x4c, 0xd0, 0x89, 0xd3, 0xc9, 0xe2, 0x5c, 0x17, 0xbb, 0x30, 0x70, 0xc6, 0x53, 0xd4, 0xa2, + 0xf1, 0x03, 0x46, 0x7d, 0xe2, 0xc1, 0xa4, 0x45, 0x73, 0x95, 0x37, 0x63, 0x09, 0xb7, 0xff, 0xd8, + 0x82, 0x51, 0xb5, 0xb4, 0x8f, 0x21, 0xd1, 0xce, 0x4b, 0x26, 0xda, 0x2d, 0x1c, 0x5e, 0x38, 0xb2, + 0x9e, 0xf7, 0x88, 0x66, 0xff, 0xea, 0x30, 0x80, 0x16, 0xa0, 0x4a, 0x77, 0x59, 0x3d, 0x75, 0xd7, + 0x7d, 0x2b, 0xbc, 0xb2, 0xca, 0x68, 0x95, 0xee, 0x6d, 0x19, 0xad, 0x2a, 0x9c, 0x91, 0x96, 0x05, + 0x3f, 0xec, 0xbb, 0x14, 0x44, 0x4a, 0x16, 0x96, 0x67, 0x1f, 0x15, 0x84, 0xce, 0x2c, 0x66, 0x21, + 0xe1, 0xec, 0x67, 0x13, 0x06, 0xcd, 0xd0, 0xbe, 0x56, 0xa6, 0x5a, 0xfe, 0x4b, 0x1b, 0xf2, 0x5e, + 0xb4, 0xd4, 0xf2, 0x5f, 0xba, 0x58, 0xc5, 0x1a, 0x27, 0x5b, 0x07, 0x54, 0x72, 0xd2, 0x01, 0x70, + 0x60, 0x1d, 0x20, 0xa5, 0xd1, 0x70, 0x4f, 0x69, 0x24, 0x0f, 0x15, 0x46, 0x7a, 0x1e, 0x2a, 0xbc, + 0x1d, 0xc6, 0x5c, 0x7f, 0x93, 0x84, 0x6e, 0x4c, 0xea, 0x6c, 0x2d, 0x30, 0x49, 0x55, 0xd6, 0x16, + 0xc0, 0x62, 0x02, 0x8a, 0x53, 0xd8, 0x49, 0x11, 0x3a, 0xd6, 0x87, 0x08, 0xed, 0xa1, 0xb8, 0xc6, + 0xf3, 0x51, 0x5c, 0x27, 0x0e, 0xaf, 0xb8, 0x4e, 0x1e, 0xa9, 0xe2, 0x42, 0xb9, 0x28, 0xae, 0xbe, + 0x74, 0x82, 0xb1, 0x33, 0x3d, 0xbd, 0xcf, 0xce, 0xb4, 0x97, 0xd6, 0x3a, 0x73, 0xd7, 0x5a, 0x2b, + 0x5b, 0x21, 0x3d, 0x70, 0xd4, 0x0a, 0xe9, 0x63, 0x05, 0x38, 0xa3, 0x45, 0x36, 0x5d, 0x28, 0xee, + 0x06, 0x15, 0x5a, 0xec, 0x16, 0x4e, 0x7e, 0x46, 0x67, 0xa4, 0x6b, 0xea, 0xcc, 0x4f, 0x05, 0xc1, + 0x06, 0x16, 0xcb, 0x7a, 0x24, 0x21, 0x2b, 0x59, 0x9f, 0x96, 0xe7, 0x73, 0xa2, 0x1d, 0x2b, 0x0c, + 0x3a, 0x15, 0xe9, 0x6f, 0x91, 0xbd, 0x9e, 0x2e, 0x86, 0x3a, 0xa7, 0x41, 0xd8, 0xc4, 0x43, 0x4f, + 0x72, 0x26, 0x4c, 0x96, 0x50, 0x99, 0x3e, 0xc2, 0x37, 0x22, 0x4a, 0x7c, 0x28, 0xa8, 0xec, 0x0e, + 0x4b, 0x6f, 0x2d, 0x75, 0x77, 0x87, 0x85, 0xbb, 0x29, 0x0c, 0xfb, 0x7f, 0x59, 0xf0, 0x50, 0xe6, + 0x50, 0x1c, 0x83, 0x9e, 0xde, 0x49, 0xea, 0xe9, 0x6a, 0x5e, 0x9b, 0x18, 0xe3, 0x2d, 0x7a, 0xe8, + 0xec, 0xff, 0x6c, 0xc1, 0x98, 0xc6, 0x3f, 0x86, 0x57, 0x75, 0x93, 0xaf, 0x9a, 0xdf, 0x7e, 0xad, + 0xd2, 0xf5, 0x6e, 0xbf, 0x53, 0x00, 0x55, 0xa0, 0x78, 0xa6, 0x26, 0xcb, 0xbf, 0xef, 0x73, 0x6a, + 0xdc, 0x81, 0x41, 0x76, 0xe8, 0x1d, 0xe5, 0x13, 0xd0, 0x93, 0xe4, 0xcf, 0x0e, 0xd0, 0x75, 0x40, + 0x01, 0xfb, 0x1b, 0x61, 0xc1, 0x90, 0x5d, 0xa8, 0xc0, 0x6b, 0xbf, 0xd6, 0x45, 0xce, 0x98, 0xbe, + 0x50, 0x41, 0xb4, 0x63, 0x85, 0x41, 0x35, 0x89, 0x5b, 0x0b, 0xfc, 0x39, 0xcf, 0x89, 0xe4, 0xc5, + 0xdc, 0x4a, 0x93, 0x2c, 0x4a, 0x00, 0xd6, 0x38, 0xec, 0x3c, 0xdc, 0x8d, 0x5a, 0x9e, 0xd3, 0x31, + 0x76, 0xe5, 0x46, 0x95, 0x16, 0x05, 0xc2, 0x26, 0x9e, 0xdd, 0x84, 0x89, 0xe4, 0x4b, 0xcc, 0x93, + 0x0d, 0x16, 0x8c, 0xda, 0xd7, 0x70, 0x4e, 0x43, 0xc5, 0x61, 0x4f, 0x2d, 0xb5, 0x1d, 0x21, 0x13, + 0x74, 0x48, 0xa6, 0x04, 0x60, 0x8d, 0x63, 0xff, 0x53, 0x0b, 0x4e, 0x65, 0x0c, 0x5a, 0x8e, 0xc9, + 0x91, 0xb1, 0x96, 0x36, 0x59, 0x36, 0xc0, 0x0f, 0xc0, 0x50, 0x9d, 0x6c, 0x38, 0x32, 0xdc, 0xd1, + 0x90, 0x9e, 0xf3, 0xbc, 0x19, 0x4b, 0xb8, 0xfd, 0x9b, 0x05, 0x18, 0x4f, 0xf6, 0x35, 0x62, 0x69, + 0x43, 0x7c, 0x98, 0xdc, 0xa8, 0x16, 0x6c, 0x93, 0xb0, 0x43, 0xdf, 0xdc, 0x4a, 0xa5, 0x0d, 0x75, + 0x61, 0xe0, 0x8c, 0xa7, 0x58, 0x79, 0xf2, 0xba, 0x1a, 0x6d, 0x39, 0x23, 0xaf, 0xe7, 0x39, 0x23, + 0xf5, 0xc7, 0x34, 0x43, 0x23, 0x14, 0x4b, 0x6c, 0xf2, 0xa7, 0xb6, 0x08, 0x8b, 0xc3, 0x9e, 0x6d, + 0xbb, 0x5e, 0xec, 0xfa, 0xe2, 0x95, 0xc5, 0x5c, 0x55, 0xb6, 0xc8, 0x72, 0x37, 0x0a, 0xce, 0x7a, + 0xce, 0xfe, 0xf6, 0x00, 0xa8, 0xc4, 0x7f, 0x16, 0xba, 0x96, 0x53, 0xe0, 0xdf, 0x41, 0x93, 0xcf, + 0xd4, 0xdc, 0x1a, 0xd8, 0x2b, 0x96, 0x84, 0xbb, 0x72, 0x4c, 0x7f, 0xae, 0x1a, 0xb0, 0x35, 0x0d, + 0xc2, 0x26, 0x1e, 0xed, 0x89, 0xe7, 0x6e, 0x13, 0xfe, 0xd0, 0x60, 0xb2, 0x27, 0x4b, 0x12, 0x80, + 0x35, 0x0e, 0xed, 0x49, 0xdd, 0xdd, 0xd8, 0x10, 0x7e, 0x09, 0xd5, 0x13, 0x3a, 0x3a, 0x98, 0x41, + 0xf8, 0x05, 0x16, 0xc1, 0x96, 0xb0, 0xbf, 0x8d, 0x0b, 0x2c, 0x82, 0x2d, 0xcc, 0x20, 0xf4, 0x2b, + 0xf9, 0x41, 0xd8, 0x74, 0x3c, 0xf7, 0x35, 0x52, 0x57, 0x5c, 0x84, 0xdd, 0xad, 0xbe, 0xd2, 0xd5, + 0x6e, 0x14, 0x9c, 0xf5, 0x1c, 0x9d, 0xd0, 0xad, 0x90, 0xd4, 0xdd, 0x5a, 0x6c, 0x52, 0x83, 0xe4, + 0x84, 0x5e, 0xed, 0xc2, 0xc0, 0x19, 0x4f, 0xa1, 0x19, 0x18, 0x97, 0x85, 0x1b, 0x64, 0x29, 0xb0, + 0xe1, 0x64, 0xe9, 0x21, 0x9c, 0x04, 0xe3, 0x34, 0x3e, 0x15, 0x92, 0x4d, 0x51, 0xc8, 0x90, 0x99, + 0xe9, 0x86, 0x90, 0x94, 0x05, 0x0e, 0xb1, 0xc2, 0xb0, 0x3f, 0x54, 0xa4, 0x4a, 0xbd, 0x47, 0xbd, + 0xd0, 0x63, 0x0b, 0x34, 0x4d, 0xce, 0xc8, 0x81, 0x3e, 0x66, 0xe4, 0xb3, 0x30, 0x72, 0x33, 0x0a, + 0x7c, 0x15, 0xc4, 0x59, 0xea, 0x19, 0xc4, 0x69, 0x60, 0x65, 0x07, 0x71, 0x0e, 0xe6, 0x15, 0xc4, + 0x39, 0x74, 0x97, 0x41, 0x9c, 0xbf, 0x57, 0x02, 0x75, 0x43, 0xd9, 0x55, 0x12, 0xdf, 0x0a, 0xc2, + 0x2d, 0xd7, 0x6f, 0xb0, 0x22, 0x04, 0x5f, 0xb4, 0x64, 0x1d, 0x83, 0x25, 0x33, 0x09, 0x6f, 0x23, + 0xa7, 0x5b, 0xa6, 0x12, 0xcc, 0xa6, 0xd6, 0x0c, 0x46, 0xa9, 0x8b, 0xd4, 0x4d, 0x10, 0x4e, 0xf4, + 0x08, 0xbd, 0x1f, 0x40, 0x3a, 0x71, 0x37, 0xa4, 0x04, 0x5e, 0xcc, 0xa7, 0x7f, 0x98, 0x6c, 0x68, + 0x93, 0x7a, 0x4d, 0x31, 0xc1, 0x06, 0x43, 0xf4, 0x31, 0x9d, 0xa0, 0xc8, 0xb3, 0x3d, 0xde, 0x7b, + 0x24, 0x63, 0xd3, 0x4f, 0x7a, 0x22, 0x86, 0x21, 0xd7, 0x6f, 0xd0, 0x79, 0x22, 0x82, 0xdd, 0xde, + 0x92, 0x55, 0x2c, 0x66, 0x29, 0x70, 0xea, 0xb3, 0x8e, 0xe7, 0xf8, 0x35, 0x12, 0x2e, 0x72, 0x74, + 0xad, 0x41, 0x45, 0x03, 0x96, 0x84, 0xba, 0xae, 0x51, 0x2b, 0xf5, 0x73, 0x8d, 0xda, 0xd9, 0x77, + 0xc0, 0xc9, 0xae, 0x8f, 0x79, 0xa0, 0x6c, 0xc4, 0xbb, 0x4f, 0x64, 0xb4, 0x7f, 0xbf, 0xa2, 0x95, + 0xd6, 0xd5, 0xa0, 0xce, 0x6f, 0xe5, 0x0a, 0xf5, 0x17, 0x15, 0x26, 0x73, 0x8e, 0x53, 0x44, 0xa9, + 0x19, 0xa3, 0x11, 0x9b, 0x2c, 0xe9, 0x1c, 0x6d, 0x39, 0x21, 0xf1, 0x8f, 0x7a, 0x8e, 0xae, 0x2a, + 0x26, 0xd8, 0x60, 0x88, 0x36, 0x13, 0xe9, 0x48, 0x17, 0x0f, 0x9f, 0x8e, 0xc4, 0x4a, 0xf7, 0x65, + 0x5d, 0x5e, 0xf3, 0x19, 0x0b, 0xc6, 0xfc, 0xc4, 0xcc, 0xcd, 0x27, 0x02, 0x39, 0x7b, 0x55, 0xf0, + 0x0b, 0x2e, 0x93, 0x6d, 0x38, 0xc5, 0x3f, 0x4b, 0xa5, 0x95, 0x0e, 0xa8, 0xd2, 0xf4, 0xad, 0x80, + 0x83, 0xbd, 0x6e, 0x05, 0x44, 0xbe, 0xba, 0xab, 0x75, 0x28, 0xf7, 0xbb, 0x5a, 0x21, 0xe3, 0x9e, + 0xd6, 0x1b, 0x50, 0xa9, 0x85, 0xc4, 0x89, 0xef, 0xf2, 0xda, 0x4e, 0x16, 0xdb, 0x31, 0x27, 0x09, + 0x60, 0x4d, 0x0b, 0x7d, 0x40, 0xc9, 0xb3, 0x4a, 0x9e, 0xd6, 0x2c, 0x5d, 0x8a, 0x7d, 0x49, 0xb1, + 0xcf, 0xa6, 0x92, 0xac, 0x21, 0x8f, 0x5c, 0xd8, 0x44, 0x2f, 0xbe, 0xbb, 0x12, 0xab, 0xff, 0xef, + 0x00, 0x9c, 0x90, 0xdd, 0x97, 0xd9, 0x24, 0xd4, 0x5e, 0xe1, 0xf3, 0x40, 0xef, 0x5d, 0x94, 0xbd, + 0x72, 0x49, 0x02, 0xb0, 0xc6, 0xa1, 0xf6, 0x71, 0x3b, 0x22, 0x2b, 0x2d, 0xe2, 0x2f, 0xb9, 0xeb, + 0x91, 0x38, 0x1c, 0x57, 0xef, 0x7d, 0x4d, 0x83, 0xb0, 0x89, 0x47, 0xf7, 0x5a, 0x8e, 0xb1, 0x89, + 0x30, 0xf6, 0x5a, 0x72, 0xe3, 0x20, 0xe1, 0xe8, 0x17, 0x33, 0x0b, 0xca, 0xe7, 0x93, 0x83, 0xd9, + 0x95, 0x44, 0x73, 0xc0, 0x4b, 0xc0, 0xff, 0x91, 0x05, 0x67, 0x78, 0xab, 0x1c, 0xc9, 0x6b, 0xad, + 0xba, 0x13, 0x93, 0x28, 0x9f, 0x8b, 0x68, 0x32, 0xfa, 0xa7, 0xdd, 0xfd, 0x59, 0x6c, 0x71, 0x76, + 0x6f, 0xd0, 0xa7, 0x2d, 0x18, 0xdf, 0x4a, 0x14, 0xfe, 0x91, 0xaa, 0xfc, 0xb0, 0x95, 0x35, 0x12, + 0x44, 0xb5, 0xe8, 0x4b, 0xb6, 0x47, 0x38, 0xcd, 0xdd, 0xfe, 0x9f, 0x16, 0x98, 0x6a, 0xed, 0xf8, + 0xeb, 0x05, 0x1d, 0xdc, 0x34, 0x97, 0xd6, 0x7e, 0xa9, 0xa7, 0xb5, 0xff, 0x28, 0x14, 0xdb, 0x6e, + 0x5d, 0xec, 0xf7, 0xf4, 0x91, 0xfd, 0xe2, 0x3c, 0xa6, 0xed, 0xf6, 0xbf, 0x2a, 0x69, 0xb7, 0x94, + 0x48, 0x71, 0xfc, 0x9e, 0x78, 0xed, 0x0d, 0x55, 0x51, 0x93, 0xbf, 0xf9, 0xd5, 0xae, 0x8a, 0x9a, + 0x3f, 0x7a, 0xf0, 0x0c, 0x56, 0x3e, 0x40, 0xbd, 0x0a, 0x6a, 0x0e, 0xed, 0x93, 0xbe, 0x7a, 0x13, + 0xca, 0x74, 0x4b, 0xcc, 0xfc, 0xcb, 0xe5, 0x44, 0xa7, 0xca, 0x97, 0x44, 0xfb, 0x9d, 0xdd, 0xc9, + 0x1f, 0x39, 0x78, 0xb7, 0xe4, 0xd3, 0x58, 0xd1, 0x47, 0x11, 0x54, 0xe8, 0x6f, 0x96, 0x69, 0x2b, + 0x36, 0xdb, 0xd7, 0x94, 0xcc, 0x94, 0x80, 0x5c, 0xd2, 0x78, 0x35, 0x1f, 0xe4, 0x43, 0x85, 0x22, + 0x72, 0xa6, 0x7c, 0x4f, 0xbe, 0xaa, 0xf2, 0x5d, 0x25, 0xe0, 0xce, 0xee, 0xe4, 0x0b, 0x07, 0x67, + 0xaa, 0x1e, 0xc7, 0x9a, 0x85, 0xfd, 0xd7, 0x03, 0x7a, 0xee, 0x8a, 0x42, 0xaa, 0xdf, 0x13, 0x73, + 0xf7, 0xf9, 0xd4, 0xdc, 0x3d, 0xd7, 0x35, 0x77, 0xc7, 0xf4, 0x65, 0xfa, 0x89, 0xd9, 0x78, 0xdc, + 0x86, 0xd9, 0xfe, 0xfe, 0x1f, 0x66, 0x91, 0xbe, 0xda, 0x76, 0x43, 0x12, 0xad, 0x86, 0x6d, 0xdf, + 0xf5, 0x1b, 0x6c, 0x3a, 0x96, 0x4d, 0x8b, 0x34, 0x01, 0xc6, 0x69, 0x7c, 0xf4, 0x14, 0x94, 0xe9, + 0x37, 0xbf, 0xe1, 0x6c, 0xf3, 0x59, 0x65, 0xd4, 0xde, 0xab, 0x8a, 0x76, 0xac, 0x30, 0xd0, 0x26, + 0x3c, 0x22, 0x09, 0xcc, 0x13, 0x8f, 0x88, 0xdb, 0xf0, 0x37, 0xdc, 0xb0, 0xc9, 0x03, 0xf6, 0x79, + 0xa4, 0xc8, 0x9b, 0x05, 0x85, 0x47, 0xf0, 0x1e, 0xb8, 0x78, 0x4f, 0x4a, 0xf6, 0x57, 0x58, 0xfc, + 0x84, 0x51, 0x4c, 0x80, 0xce, 0x3e, 0xcf, 0x6d, 0xba, 0xb2, 0x44, 0xa0, 0x9a, 0x7d, 0x4b, 0xb4, + 0x11, 0x73, 0x18, 0xba, 0x05, 0x43, 0xeb, 0xfc, 0xd2, 0xe2, 0x7c, 0x2e, 0x48, 0x11, 0x37, 0x20, + 0xb3, 0x3a, 0xbb, 0xf2, 0x3a, 0xe4, 0x3b, 0xfa, 0x27, 0x96, 0xdc, 0xec, 0xaf, 0x97, 0x60, 0x5c, + 0x06, 0x7f, 0x5d, 0x72, 0x23, 0x16, 0x16, 0x61, 0x16, 0x1f, 0x2f, 0xec, 0x5b, 0x7c, 0xfc, 0x3d, + 0x00, 0x75, 0xd2, 0xf2, 0x82, 0x0e, 0x33, 0xc4, 0x07, 0x0e, 0x6c, 0x88, 0xab, 0xbd, 0xdb, 0xbc, + 0xa2, 0x82, 0x0d, 0x8a, 0xa2, 0x2e, 0x22, 0xaf, 0x65, 0x9e, 0xaa, 0x8b, 0x68, 0x5c, 0xa3, 0x34, + 0x78, 0xbc, 0xd7, 0x28, 0xb9, 0x30, 0xce, 0xbb, 0xa8, 0x52, 0xf6, 0xef, 0x22, 0x33, 0x9f, 0x25, + 0x3d, 0xcd, 0x27, 0xc9, 0xe0, 0x34, 0x5d, 0xf3, 0x8e, 0xa4, 0xf2, 0x71, 0xdf, 0x91, 0xf4, 0x56, + 0xa8, 0xc8, 0xef, 0xcc, 0x77, 0x43, 0xa2, 0xec, 0x89, 0x9c, 0x06, 0x11, 0xd6, 0xf0, 0xae, 0xea, + 0x23, 0x70, 0xaf, 0xaa, 0x8f, 0xd8, 0x9f, 0x2a, 0xd0, 0x1d, 0x03, 0xef, 0x97, 0x2a, 0xa4, 0xf5, + 0x04, 0x0c, 0x3a, 0xed, 0x78, 0x33, 0xe8, 0xba, 0xf6, 0x78, 0x86, 0xb5, 0x62, 0x01, 0x45, 0x4b, + 0x30, 0x50, 0xd7, 0xc5, 0x91, 0x0e, 0xf2, 0x3d, 0xb5, 0x33, 0xdc, 0x89, 0x09, 0x66, 0x54, 0xd0, + 0x23, 0x30, 0x10, 0x3b, 0x0d, 0x99, 0xa7, 0xc9, 0x72, 0xf3, 0xd7, 0x9c, 0x46, 0x84, 0x59, 0xeb, + 0x41, 0x4a, 0xc9, 0xbe, 0x00, 0xa3, 0x91, 0xdb, 0xf0, 0x9d, 0xb8, 0x1d, 0x12, 0xe3, 0xbc, 0x58, + 0x47, 0x0b, 0x99, 0x40, 0x9c, 0xc4, 0xb5, 0x7f, 0x6b, 0x04, 0x4e, 0x57, 0xe7, 0x96, 0xe5, 0x65, + 0x18, 0x47, 0x96, 0x6a, 0x99, 0xc5, 0xe3, 0xf8, 0x52, 0x2d, 0x7b, 0x70, 0xf7, 0x8c, 0x54, 0x4b, + 0xcf, 0x48, 0xb5, 0x4c, 0xe6, 0xbd, 0x15, 0xf3, 0xc8, 0x7b, 0xcb, 0xea, 0x41, 0x3f, 0x79, 0x6f, + 0x47, 0x96, 0x7b, 0xb9, 0x67, 0x87, 0x0e, 0x94, 0x7b, 0xa9, 0x12, 0x53, 0x73, 0xc9, 0x48, 0xea, + 0xf1, 0xa9, 0x32, 0x13, 0x53, 0x55, 0x52, 0x20, 0xcf, 0xb6, 0x13, 0xa2, 0xfe, 0xe5, 0xfc, 0x3b, + 0xd0, 0x47, 0x52, 0xa0, 0x48, 0xf8, 0x33, 0x13, 0x51, 0x87, 0xf2, 0x48, 0x44, 0xcd, 0xea, 0xce, + 0xbe, 0x89, 0xa8, 0x2f, 0xc0, 0x68, 0xcd, 0x0b, 0x7c, 0xb2, 0x1a, 0x06, 0x71, 0x50, 0x0b, 0xe4, + 0xc5, 0xab, 0xfa, 0xde, 0x30, 0x13, 0x88, 0x93, 0xb8, 0xbd, 0xb2, 0x58, 0x2b, 0x87, 0xcd, 0x62, + 0x85, 0x7b, 0x94, 0xc5, 0xfa, 0x33, 0xba, 0xde, 0xc2, 0x30, 0xfb, 0x22, 0xef, 0xc9, 0xff, 0x8b, + 0xf4, 0x75, 0xb3, 0xea, 0xeb, 0xfc, 0xde, 0x61, 0x6a, 0x82, 0xcf, 0x05, 0x4d, 0x6a, 0xf8, 0x8d, + 0xb0, 0x21, 0x79, 0xe5, 0x08, 0x26, 0xec, 0x8d, 0xaa, 0x66, 0xa3, 0xee, 0x22, 0xd6, 0x4d, 0x38, + 0xd9, 0x91, 0xc3, 0xd4, 0x83, 0xf8, 0x7c, 0x01, 0xbe, 0x6f, 0xdf, 0x2e, 0xa0, 0x5b, 0x00, 0xb1, + 0xd3, 0x10, 0x13, 0x55, 0x1c, 0x95, 0x1d, 0x32, 0xa4, 0x77, 0x4d, 0xd2, 0xe3, 0x85, 0x8c, 0xd4, + 0x5f, 0x76, 0x08, 0x25, 0x7f, 0xb3, 0x48, 0xde, 0xc0, 0xeb, 0xaa, 0xf7, 0x8a, 0x03, 0x8f, 0x60, + 0x06, 0xa1, 0xea, 0x3f, 0x24, 0x0d, 0x6a, 0xd2, 0x16, 0x93, 0xea, 0x1f, 0xb3, 0x56, 0x2c, 0xa0, + 0xe8, 0x39, 0x18, 0x76, 0x3c, 0x8f, 0xa7, 0x8b, 0x91, 0x48, 0x5c, 0xe8, 0xa7, 0xfd, 0xa3, 0x1a, + 0x84, 0x4d, 0x3c, 0xfb, 0x2f, 0x0b, 0x30, 0xb9, 0x8f, 0x4c, 0xe9, 0x4a, 0x13, 0x2e, 0xf5, 0x9d, + 0x26, 0x2c, 0x52, 0x68, 0x06, 0x7b, 0xa4, 0xd0, 0x3c, 0x07, 0xc3, 0x31, 0x71, 0x9a, 0x22, 0x08, + 0x50, 0xf8, 0x1c, 0xf4, 0xd9, 0xbf, 0x06, 0x61, 0x13, 0x8f, 0x4a, 0xb1, 0x31, 0xa7, 0x56, 0x23, + 0x51, 0x24, 0x73, 0x64, 0x84, 0x1f, 0x3d, 0xb7, 0x04, 0x1c, 0x76, 0x3c, 0x31, 0x93, 0x60, 0x81, + 0x53, 0x2c, 0xd3, 0x03, 0x5e, 0xe9, 0x73, 0xc0, 0xbf, 0x54, 0x80, 0x47, 0xf7, 0xd4, 0x6e, 0x7d, + 0xa7, 0x2f, 0xb5, 0x23, 0x12, 0xa6, 0x27, 0xce, 0xb5, 0x88, 0x84, 0x98, 0x41, 0xf8, 0x28, 0xb5, + 0x5a, 0x2a, 0x80, 0x3b, 0xff, 0x5c, 0x3e, 0x3e, 0x4a, 0x09, 0x16, 0x38, 0xc5, 0xf2, 0x6e, 0xa7, + 0xe5, 0xd7, 0x07, 0xe0, 0xf1, 0x3e, 0x6c, 0x80, 0x1c, 0x73, 0x1e, 0x93, 0xf9, 0xb9, 0xc5, 0x7b, + 0x94, 0x9f, 0x7b, 0x77, 0xc3, 0xf5, 0x46, 0x5a, 0x6f, 0x5f, 0xb9, 0x95, 0x5f, 0x29, 0xc0, 0xd9, + 0xde, 0x06, 0x0b, 0xfa, 0x31, 0x18, 0x0f, 0x55, 0xd0, 0xa3, 0x99, 0xda, 0x7b, 0x8a, 0x7b, 0x76, + 0x12, 0x20, 0x9c, 0xc6, 0x45, 0x53, 0x00, 0x2d, 0x27, 0xde, 0x8c, 0x2e, 0xec, 0xb8, 0x51, 0x2c, + 0x0a, 0x7c, 0x8d, 0xf1, 0xb3, 0x5d, 0xd9, 0x8a, 0x0d, 0x0c, 0xca, 0x8e, 0xfd, 0x9b, 0x0f, 0xae, + 0x06, 0x31, 0x7f, 0x88, 0x6f, 0xb6, 0x4e, 0xc9, 0x8b, 0xc2, 0x0c, 0x10, 0x4e, 0xe3, 0x52, 0x76, + 0xec, 0xdc, 0x8d, 0x77, 0x94, 0xef, 0xc2, 0x18, 0xbb, 0x25, 0xd5, 0x8a, 0x0d, 0x8c, 0x74, 0xd2, + 0x72, 0x69, 0xff, 0xa4, 0x65, 0xfb, 0x5f, 0x16, 0xe0, 0xa1, 0x9e, 0x06, 0x6f, 0x7f, 0x62, 0xea, + 0xfe, 0x4b, 0x34, 0xbe, 0xcb, 0x15, 0x76, 0xb0, 0x04, 0xd5, 0x3f, 0xe9, 0x31, 0xd3, 0x44, 0x82, + 0xea, 0xdd, 0xd7, 0xdd, 0xb8, 0xff, 0xc6, 0xb3, 0x2b, 0x27, 0x75, 0xe0, 0x00, 0x39, 0xa9, 0xa9, + 0x8f, 0x51, 0xea, 0x53, 0x3b, 0xfc, 0xd9, 0x40, 0xcf, 0xe1, 0xa5, 0x1b, 0xe4, 0xbe, 0xfc, 0xe6, + 0xf3, 0x70, 0xc2, 0xf5, 0xd9, 0xa5, 0x91, 0xd5, 0xf6, 0xba, 0xa8, 0xf9, 0xc4, 0x0b, 0x9b, 0xaa, + 0xc4, 0x97, 0xc5, 0x14, 0x1c, 0x77, 0x3d, 0x71, 0x1f, 0xe6, 0x08, 0xdf, 0xdd, 0x90, 0x1e, 0x50, + 0x72, 0xaf, 0xc0, 0x19, 0x39, 0x14, 0x9b, 0x4e, 0x48, 0xea, 0x42, 0xd9, 0x46, 0x22, 0xd5, 0xe9, + 0x21, 0x9e, 0x2e, 0x95, 0x81, 0x80, 0xb3, 0x9f, 0x63, 0xf7, 0xf4, 0x05, 0x2d, 0xb7, 0x26, 0xb6, + 0x82, 0xfa, 0x9e, 0x3e, 0xda, 0x88, 0x39, 0x4c, 0xeb, 0x8b, 0xca, 0xf1, 0xe8, 0x8b, 0xf7, 0x40, + 0x45, 0x8d, 0x37, 0xcf, 0xda, 0x50, 0x93, 0xbc, 0x2b, 0x6b, 0x43, 0xcd, 0x70, 0x03, 0x6b, 0xbf, + 0x3b, 0xae, 0x7f, 0x08, 0x46, 0x94, 0xf7, 0xab, 0xdf, 0xdb, 0x12, 0xed, 0xff, 0x57, 0x80, 0xd4, + 0x7d, 0x46, 0x68, 0x07, 0x2a, 0x75, 0x79, 0xcb, 0x74, 0x3e, 0x85, 0x75, 0xd5, 0xa5, 0xd5, 0xfa, + 0xf8, 0x47, 0x35, 0x61, 0xcd, 0x0c, 0xbd, 0x8f, 0xd7, 0xb0, 0x15, 0xac, 0x0b, 0x79, 0xe4, 0x89, + 0x57, 0x15, 0x3d, 0xf3, 0x3a, 0x34, 0xd9, 0x86, 0x0d, 0x7e, 0x28, 0x86, 0xca, 0xa6, 0xbc, 0xb7, + 0x29, 0x1f, 0x71, 0xa7, 0xae, 0x81, 0xe2, 0x26, 0x9a, 0xfa, 0x8b, 0x35, 0x23, 0xfb, 0x8f, 0x0b, + 0x70, 0x3a, 0xf9, 0x01, 0xc4, 0x71, 0xdd, 0xaf, 0x5a, 0xf0, 0xa0, 0xe7, 0x44, 0x71, 0xb5, 0xcd, + 0x36, 0x0a, 0x1b, 0x6d, 0x6f, 0x25, 0x55, 0xee, 0xf8, 0xb0, 0xce, 0x16, 0x45, 0x38, 0x7d, 0xcf, + 0xd7, 0xec, 0xc3, 0xb7, 0x77, 0x27, 0x1f, 0x5c, 0xca, 0x66, 0x8e, 0x7b, 0xf5, 0x0a, 0x7d, 0xc6, + 0x82, 0x13, 0xb5, 0x76, 0x18, 0x12, 0x3f, 0xd6, 0x5d, 0xe5, 0x5f, 0xf1, 0x6a, 0x2e, 0x03, 0xa9, + 0x3b, 0x78, 0x9a, 0x0a, 0xd4, 0xb9, 0x14, 0x2f, 0xdc, 0xc5, 0xdd, 0xfe, 0x79, 0xaa, 0x39, 0x7b, + 0xbe, 0xe7, 0xdf, 0xb0, 0x8b, 0xc9, 0xfe, 0x7c, 0x10, 0x46, 0x13, 0x35, 0x9d, 0x13, 0x47, 0x5c, + 0xd6, 0xbe, 0x47, 0x5c, 0x2c, 0x39, 0xaf, 0xed, 0xcb, 0x6b, 0x93, 0x8d, 0xe4, 0xbc, 0xb6, 0x4f, + 0x30, 0x87, 0x89, 0x21, 0xc5, 0x6d, 0x5f, 0x64, 0x1b, 0x98, 0x43, 0x8a, 0xdb, 0x3e, 0x16, 0x50, + 0xf4, 0x41, 0x0b, 0x46, 0xd8, 0xe2, 0x13, 0x07, 0x84, 0x42, 0xa1, 0x5d, 0xce, 0x61, 0xb9, 0xcb, + 0xfa, 0xe5, 0x2c, 0x3a, 0xd5, 0x6c, 0xc1, 0x09, 0x8e, 0xe8, 0x23, 0x16, 0x54, 0xd4, 0x4d, 0x8b, + 0xe2, 0x0e, 0xf4, 0x6a, 0xbe, 0x25, 0xb3, 0x53, 0x52, 0x4f, 0xd5, 0x2e, 0xc6, 0x9a, 0x31, 0x8a, + 0xd4, 0xe9, 0xdd, 0xd0, 0xd1, 0x9c, 0xde, 0x41, 0xc6, 0xc9, 0xdd, 0x5b, 0xa1, 0xd2, 0x74, 0x7c, + 0x77, 0x83, 0x44, 0x31, 0x3f, 0x50, 0x93, 0x95, 0xfc, 0x65, 0x23, 0xd6, 0x70, 0x6a, 0xec, 0x47, + 0xec, 0xc5, 0x62, 0xe3, 0x04, 0x8c, 0x19, 0xfb, 0x55, 0xdd, 0x8c, 0x4d, 0x1c, 0xf3, 0xb8, 0x0e, + 0xee, 0xe9, 0x71, 0xdd, 0xf0, 0x3e, 0xc7, 0x75, 0x55, 0x38, 0xe3, 0xb4, 0xe3, 0xe0, 0x12, 0x71, + 0xbc, 0x99, 0x38, 0x26, 0xcd, 0x56, 0x1c, 0xf1, 0x32, 0xe0, 0x23, 0xcc, 0x05, 0xac, 0xe2, 0xb7, + 0xaa, 0xc4, 0xdb, 0xe8, 0x42, 0xc2, 0xd9, 0xcf, 0xda, 0xff, 0xdc, 0x82, 0x33, 0x99, 0x53, 0xe1, + 0xfe, 0xcd, 0x64, 0xb0, 0x3f, 0x57, 0x82, 0x53, 0x19, 0x15, 0xdf, 0x51, 0xc7, 0x5c, 0x24, 0x56, + 0x1e, 0x41, 0x68, 0xc9, 0x98, 0x2a, 0xf9, 0x6d, 0x32, 0x56, 0xc6, 0xc1, 0x4e, 0xe0, 0xf5, 0x29, + 0x78, 0xf1, 0x78, 0x4f, 0xc1, 0x8d, 0xb9, 0x3e, 0x70, 0x4f, 0xe7, 0x7a, 0x69, 0x9f, 0xb9, 0xfe, + 0x55, 0x0b, 0x26, 0x9a, 0x3d, 0xae, 0x19, 0x12, 0xe7, 0x49, 0xd7, 0x8f, 0xe6, 0x12, 0xa3, 0xd9, + 0x47, 0x6e, 0xef, 0x4e, 0xf6, 0xbc, 0xdd, 0x09, 0xf7, 0xec, 0x95, 0xfd, 0xed, 0x22, 0x30, 0x7b, + 0x8d, 0x55, 0xf5, 0xed, 0xa0, 0x0f, 0x98, 0x17, 0x47, 0x58, 0x79, 0x5d, 0x72, 0xc0, 0x89, 0xab, + 0x8b, 0x27, 0xf8, 0x08, 0x66, 0xdd, 0x43, 0x91, 0x96, 0x84, 0x85, 0x3e, 0x24, 0xa1, 0x27, 0x6f, + 0xe8, 0x28, 0xe6, 0x7f, 0x43, 0x47, 0x25, 0x7d, 0x3b, 0xc7, 0xde, 0x9f, 0x78, 0xe0, 0xbe, 0xfc, + 0xc4, 0xbf, 0x64, 0x71, 0xc1, 0x93, 0xfa, 0x0a, 0xda, 0xdc, 0xb0, 0xf6, 0x30, 0x37, 0x9e, 0x82, + 0x72, 0x24, 0x24, 0xb3, 0x30, 0x4b, 0x74, 0x00, 0x94, 0x68, 0xc7, 0x0a, 0x83, 0xee, 0xba, 0x1c, + 0xcf, 0x0b, 0x6e, 0x5d, 0x68, 0xb6, 0xe2, 0x8e, 0x30, 0x50, 0xd4, 0xb6, 0x60, 0x46, 0x41, 0xb0, + 0x81, 0x65, 0x6f, 0x82, 0xb1, 0x61, 0xb8, 0xfb, 0xfb, 0x5c, 0xfb, 0xb8, 0x88, 0xfb, 0x1f, 0x16, + 0x04, 0x2b, 0xbe, 0x01, 0x78, 0x3e, 0x75, 0xf1, 0x79, 0xff, 0xa1, 0x6e, 0xef, 0x03, 0xa8, 0x05, + 0xcd, 0x16, 0xdd, 0x12, 0xaf, 0x05, 0xf9, 0xec, 0xa3, 0xe6, 0x14, 0x3d, 0x3d, 0x60, 0xba, 0x0d, + 0x1b, 0xfc, 0x12, 0x52, 0xbb, 0xb8, 0xaf, 0xd4, 0x4e, 0x08, 0xb0, 0x81, 0xbd, 0x05, 0x98, 0xfd, + 0x97, 0x16, 0x24, 0x0c, 0x3a, 0xd4, 0x82, 0x12, 0xed, 0x6e, 0x47, 0xc8, 0x82, 0x95, 0xfc, 0xac, + 0x47, 0x2a, 0x84, 0xc5, 0x02, 0x63, 0x3f, 0x31, 0x67, 0x84, 0x3c, 0x11, 0xd6, 0x97, 0xcb, 0xbe, + 0xc6, 0x64, 0x78, 0x29, 0x08, 0xb6, 0x78, 0x64, 0x8c, 0x0e, 0x11, 0xb4, 0x9f, 0x87, 0x93, 0x5d, + 0x9d, 0x62, 0x77, 0xc0, 0x06, 0x72, 0x73, 0x6e, 0x2c, 0x0c, 0x56, 0x75, 0x02, 0x73, 0x98, 0xfd, + 0x15, 0x0b, 0x4e, 0xa4, 0xc9, 0xa3, 0xd7, 0x2d, 0x38, 0x19, 0xa5, 0xe9, 0x1d, 0xd5, 0xd8, 0xa9, + 0xd0, 0xfc, 0x2e, 0x10, 0xee, 0xee, 0x84, 0xfd, 0xd7, 0x62, 0xf2, 0xdf, 0x70, 0xfd, 0x7a, 0x70, + 0x4b, 0x99, 0x40, 0x56, 0x4f, 0x13, 0x88, 0xae, 0xfc, 0xda, 0x26, 0xa9, 0xb7, 0xbd, 0xae, 0x1a, + 0x16, 0x55, 0xd1, 0x8e, 0x15, 0x06, 0x4b, 0xd9, 0x6f, 0x8b, 0x2d, 0x69, 0x6a, 0x52, 0xce, 0x8b, + 0x76, 0xac, 0x30, 0xd0, 0xb3, 0x30, 0x62, 0xbc, 0xa4, 0x9c, 0x97, 0x6c, 0x3f, 0x61, 0x28, 0xe7, + 0x08, 0x27, 0xb0, 0xd0, 0x14, 0x80, 0x32, 0xa7, 0xa4, 0x32, 0x66, 0x3e, 0x74, 0x25, 0xf3, 0x22, + 0x6c, 0x60, 0xb0, 0x02, 0x19, 0x5e, 0x3b, 0x62, 0x87, 0xc4, 0x83, 0xba, 0x80, 0xfd, 0x9c, 0x68, + 0xc3, 0x0a, 0x4a, 0xe5, 0x56, 0xd3, 0xf1, 0xdb, 0x8e, 0x47, 0x47, 0x48, 0x78, 0xc5, 0xd4, 0x32, + 0x5c, 0x56, 0x10, 0x6c, 0x60, 0xd1, 0x37, 0x8e, 0xdd, 0x26, 0x79, 0x29, 0xf0, 0x65, 0x48, 0xb5, + 0x8e, 0x1b, 0x10, 0xed, 0x58, 0x61, 0xd8, 0x7f, 0x61, 0xc1, 0xb8, 0xae, 0xcc, 0xc3, 0x7c, 0x59, + 0x09, 0x27, 0x9e, 0xb5, 0xaf, 0x13, 0x2f, 0x59, 0x87, 0xa4, 0xd0, 0x57, 0x1d, 0x12, 0xb3, 0x44, + 0x48, 0x71, 0xcf, 0x12, 0x21, 0xdf, 0x0f, 0x43, 0x5b, 0xa4, 0x63, 0xd4, 0x12, 0x19, 0xa6, 0xe6, + 0xd0, 0x15, 0xde, 0x84, 0x25, 0x0c, 0xd9, 0x30, 0x58, 0x73, 0x54, 0x05, 0xbb, 0x11, 0xbe, 0xf5, + 0x99, 0x9b, 0x61, 0x48, 0x02, 0x62, 0xaf, 0x40, 0x45, 0x1d, 0x9f, 0x4b, 0x9f, 0x9a, 0x95, 0xed, + 0x53, 0xeb, 0xab, 0x54, 0xc1, 0xec, 0xfa, 0xd7, 0xbe, 0xf3, 0xd8, 0x9b, 0xfe, 0xf0, 0x3b, 0x8f, + 0xbd, 0xe9, 0x5b, 0xdf, 0x79, 0xec, 0x4d, 0x1f, 0xbc, 0xfd, 0x98, 0xf5, 0xb5, 0xdb, 0x8f, 0x59, + 0x7f, 0x78, 0xfb, 0x31, 0xeb, 0x5b, 0xb7, 0x1f, 0xb3, 0xbe, 0x7d, 0xfb, 0x31, 0xeb, 0x33, 0xff, + 0xed, 0xb1, 0x37, 0xbd, 0x94, 0x19, 0x53, 0x4f, 0x7f, 0x3c, 0x5d, 0xab, 0x4f, 0x6f, 0x9f, 0x67, + 0x61, 0xdd, 0x74, 0x79, 0x4d, 0x1b, 0x73, 0x6a, 0x5a, 0x2e, 0xaf, 0xff, 0x1f, 0x00, 0x00, 0xff, + 0xff, 0xf2, 0x9b, 0x53, 0x7a, 0x8a, 0xf7, 0x00, 0x00, } func (m *AWSAuthConfig) Marshal() (dAtA []byte, err error) { @@ -10595,6 +10600,14 @@ func (m *KustomizeOptions) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + i-- + if m.SetNamespace { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x18 i -= len(m.BinaryPath) copy(dAtA[i:], m.BinaryPath) i = encodeVarintGenerated(dAtA, i, uint64(len(m.BinaryPath))) @@ -13300,6 +13313,54 @@ func (m *ResourceNode) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.Annotations) > 0 { + keysForAnnotations := make([]string, 0, len(m.Annotations)) + for k := range m.Annotations { + keysForAnnotations = append(keysForAnnotations, string(k)) + } + github_com_gogo_protobuf_sortkeys.Strings(keysForAnnotations) + for iNdEx := len(keysForAnnotations) - 1; iNdEx >= 0; iNdEx-- { + v := m.Annotations[string(keysForAnnotations[iNdEx])] + baseI := i + i -= len(v) + copy(dAtA[i:], v) + i = encodeVarintGenerated(dAtA, i, uint64(len(v))) + i-- + dAtA[i] = 0x12 + i -= len(keysForAnnotations[iNdEx]) + copy(dAtA[i:], keysForAnnotations[iNdEx]) + i = encodeVarintGenerated(dAtA, i, uint64(len(keysForAnnotations[iNdEx]))) + i-- + dAtA[i] = 0xa + i = encodeVarintGenerated(dAtA, i, uint64(baseI-i)) + i-- + dAtA[i] = 0x52 + } + } + if len(m.Labels) > 0 { + keysForLabels := make([]string, 0, len(m.Labels)) + for k := range m.Labels { + keysForLabels = append(keysForLabels, string(k)) + } + github_com_gogo_protobuf_sortkeys.Strings(keysForLabels) + for iNdEx := len(keysForLabels) - 1; iNdEx >= 0; iNdEx-- { + v := m.Labels[string(keysForLabels[iNdEx])] + baseI := i + i -= len(v) + copy(dAtA[i:], v) + i = encodeVarintGenerated(dAtA, i, uint64(len(v))) + i-- + dAtA[i] = 0x12 + i -= len(keysForLabels[iNdEx]) + copy(dAtA[i:], keysForLabels[iNdEx]) + i = encodeVarintGenerated(dAtA, i, uint64(len(keysForLabels[iNdEx]))) + i-- + dAtA[i] = 0xa + i = encodeVarintGenerated(dAtA, i, uint64(baseI-i)) + i-- + dAtA[i] = 0x4a + } + } if m.CreatedAt != nil { { size, err := m.CreatedAt.MarshalToSizedBuffer(dAtA[:i]) @@ -17417,6 +17478,7 @@ func (m *KustomizeOptions) Size() (n int) { n += 1 + l + sovGenerated(uint64(l)) l = len(m.BinaryPath) n += 1 + l + sovGenerated(uint64(l)) + n += 2 return n } @@ -18453,6 +18515,22 @@ func (m *ResourceNode) Size() (n int) { l = m.CreatedAt.Size() n += 1 + l + sovGenerated(uint64(l)) } + if len(m.Labels) > 0 { + for k, v := range m.Labels { + _ = k + _ = v + mapEntrySize := 1 + len(k) + sovGenerated(uint64(len(k))) + 1 + len(v) + sovGenerated(uint64(len(v))) + n += mapEntrySize + 1 + sovGenerated(uint64(mapEntrySize)) + } + } + if len(m.Annotations) > 0 { + for k, v := range m.Annotations { + _ = k + _ = v + mapEntrySize := 1 + len(k) + sovGenerated(uint64(len(k))) + 1 + len(v) + sovGenerated(uint64(len(v))) + n += mapEntrySize + 1 + sovGenerated(uint64(mapEntrySize)) + } + } return n } @@ -20672,6 +20750,7 @@ func (this *KustomizeOptions) String() string { s := strings.Join([]string{`&KustomizeOptions{`, `BuildOptions:` + fmt.Sprintf("%v", this.BuildOptions) + `,`, `BinaryPath:` + fmt.Sprintf("%v", this.BinaryPath) + `,`, + `SetNamespace:` + fmt.Sprintf("%v", this.SetNamespace) + `,`, `}`, }, "") return s @@ -21444,6 +21523,26 @@ func (this *ResourceNode) String() string { repeatedStringForInfo += strings.Replace(strings.Replace(f.String(), "InfoItem", "InfoItem", 1), `&`, ``, 1) + "," } repeatedStringForInfo += "}" + keysForLabels := make([]string, 0, len(this.Labels)) + for k := range this.Labels { + keysForLabels = append(keysForLabels, k) + } + github_com_gogo_protobuf_sortkeys.Strings(keysForLabels) + mapStringForLabels := "map[string]string{" + for _, k := range keysForLabels { + mapStringForLabels += fmt.Sprintf("%v: %v,", k, this.Labels[k]) + } + mapStringForLabels += "}" + keysForAnnotations := make([]string, 0, len(this.Annotations)) + for k := range this.Annotations { + keysForAnnotations = append(keysForAnnotations, k) + } + github_com_gogo_protobuf_sortkeys.Strings(keysForAnnotations) + mapStringForAnnotations := "map[string]string{" + for _, k := range keysForAnnotations { + mapStringForAnnotations += fmt.Sprintf("%v: %v,", k, this.Annotations[k]) + } + mapStringForAnnotations += "}" s := strings.Join([]string{`&ResourceNode{`, `ResourceRef:` + strings.Replace(strings.Replace(this.ResourceRef.String(), "ResourceRef", "ResourceRef", 1), `&`, ``, 1) + `,`, `ParentRefs:` + repeatedStringForParentRefs + `,`, @@ -21453,6 +21552,8 @@ func (this *ResourceNode) String() string { `Images:` + fmt.Sprintf("%v", this.Images) + `,`, `Health:` + strings.Replace(this.Health.String(), "HealthStatus", "HealthStatus", 1) + `,`, `CreatedAt:` + strings.Replace(fmt.Sprintf("%v", this.CreatedAt), "Time", "v1.Time", 1) + `,`, + `Labels:` + mapStringForLabels + `,`, + `Annotations:` + mapStringForAnnotations + `,`, `}`, }, "") return s @@ -38176,6 +38277,26 @@ func (m *KustomizeOptions) Unmarshal(dAtA []byte) error { } m.BinaryPath = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field SetNamespace", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.SetNamespace = bool(v != 0) default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -47628,6 +47749,260 @@ func (m *ResourceNode) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 9: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Labels", 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 + } + if m.Labels == nil { + m.Labels = make(map[string]string) + } + var mapkey string + var mapvalue string + for iNdEx < postIndex { + entryPreIndex := 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) + if fieldNum == 1 { + var stringLenmapkey uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + 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 ErrInvalidLengthGenerated + } + postStringIndexmapkey := iNdEx + intStringLenmapkey + if postStringIndexmapkey < 0 { + return ErrInvalidLengthGenerated + } + if postStringIndexmapkey > l { + return io.ErrUnexpectedEOF + } + mapkey = string(dAtA[iNdEx:postStringIndexmapkey]) + iNdEx = postStringIndexmapkey + } else if fieldNum == 2 { + var stringLenmapvalue uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLenmapvalue |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLenmapvalue := int(stringLenmapvalue) + if intStringLenmapvalue < 0 { + return ErrInvalidLengthGenerated + } + postStringIndexmapvalue := iNdEx + intStringLenmapvalue + if postStringIndexmapvalue < 0 { + return ErrInvalidLengthGenerated + } + if postStringIndexmapvalue > l { + return io.ErrUnexpectedEOF + } + mapvalue = string(dAtA[iNdEx:postStringIndexmapvalue]) + iNdEx = postStringIndexmapvalue + } else { + iNdEx = entryPreIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > postIndex { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + m.Labels[mapkey] = mapvalue + iNdEx = postIndex + case 10: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Annotations", 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 + } + if m.Annotations == nil { + m.Annotations = make(map[string]string) + } + var mapkey string + var mapvalue string + for iNdEx < postIndex { + entryPreIndex := 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) + if fieldNum == 1 { + var stringLenmapkey uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + 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 ErrInvalidLengthGenerated + } + postStringIndexmapkey := iNdEx + intStringLenmapkey + if postStringIndexmapkey < 0 { + return ErrInvalidLengthGenerated + } + if postStringIndexmapkey > l { + return io.ErrUnexpectedEOF + } + mapkey = string(dAtA[iNdEx:postStringIndexmapkey]) + iNdEx = postStringIndexmapkey + } else if fieldNum == 2 { + var stringLenmapvalue uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLenmapvalue |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLenmapvalue := int(stringLenmapvalue) + if intStringLenmapvalue < 0 { + return ErrInvalidLengthGenerated + } + postStringIndexmapvalue := iNdEx + intStringLenmapvalue + if postStringIndexmapvalue < 0 { + return ErrInvalidLengthGenerated + } + if postStringIndexmapvalue > l { + return io.ErrUnexpectedEOF + } + mapvalue = string(dAtA[iNdEx:postStringIndexmapvalue]) + iNdEx = postStringIndexmapvalue + } else { + iNdEx = entryPreIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > postIndex { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + m.Annotations[mapkey] = mapvalue + 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 6823a76261de4..bfb86e344710a 100644 --- a/pkg/apis/application/v1alpha1/generated.proto +++ b/pkg/apis/application/v1alpha1/generated.proto @@ -1236,6 +1236,8 @@ message KustomizeOptions { // BinaryPath holds optional path to kustomize binary optional string binaryPath = 2; + + optional bool setNamespace = 3; } message KustomizePatch { @@ -1937,6 +1939,12 @@ message ResourceNode { optional HealthStatus health = 7; optional .k8s.io.apimachinery.pkg.apis.meta.v1.Time createdAt = 8; + + // available for managed resource + map labels = 9; + + // available for managed resource without k8s-last-applied-configuration + map annotations = 10; } // ResourceOverride holds configuration to customize resource diffing and health assessment diff --git a/pkg/apis/application/v1alpha1/types.go b/pkg/apis/application/v1alpha1/types.go index 524f574f880ee..d58f41622b892 100644 --- a/pkg/apis/application/v1alpha1/types.go +++ b/pkg/apis/application/v1alpha1/types.go @@ -1357,7 +1357,9 @@ type SyncOperation struct { // If omitted, will use the revision specified in app spec. Revisions []string `json:"revisions,omitempty" protobuf:"bytes,11,opt,name=revisions"` // SelfHealAttemptsCount contains the number of auto-heal attempts - SelfHealAttemptsCount int64 `json:"autoHealAttemptsCount,omitempty" protobuf:"bytes,12,opt,name=autoHealAttemptsCount"` + SelfHealAttemptsCount int64 `json:"autoHealAttemptsCount,omitempty" protobuf:"bytes,12,opt,name=autoHealAttemptsCount"` + ChangeRevisions []string `json:"changeRevisions,omitempty" protobuf:"-"` + ChangeRevision string `json:"changeRevision,omitempty" protobuf:"-"` } // IsApplyStrategy returns true if the sync strategy is "apply" @@ -1965,6 +1967,15 @@ type ResourceRef struct { UID string `json:"uid,omitempty" protobuf:"bytes,6,opt,name=uid"` } +func (r ResourceRef) IsEqual(other ResourceRef) bool { + return (r.Group == other.Group && + r.Version == other.Version && + r.Kind == other.Kind && + r.Namespace == other.Namespace && + r.Name == other.Name) || + r.UID == other.UID +} + // ResourceNode contains information about live resource and its children // TODO: describe members of this type type ResourceNode struct { @@ -1976,6 +1987,10 @@ type ResourceNode struct { Images []string `json:"images,omitempty" protobuf:"bytes,6,opt,name=images"` Health *HealthStatus `json:"health,omitempty" protobuf:"bytes,7,opt,name=health"` CreatedAt *metav1.Time `json:"createdAt,omitempty" protobuf:"bytes,8,opt,name=createdAt"` + // available for managed resource + Labels map[string]string `json:"labels,omitempty" protobuf:"bytes,9,opt,name=labels"` + // available for managed resource without k8s-last-applied-configuration + Annotations map[string]string `json:"annotations,omitempty" protobuf:"bytes,10,opt,name=annotations"` } // FullName returns a resource node's full name in the format "group/kind/namespace/name" @@ -1993,6 +2008,42 @@ func (n *ResourceNode) GroupKindVersion() schema.GroupVersionKind { } } +func (n *ResourceNode) GetAllChildNodes(tree *ApplicationTree, kind string) []ResourceNode { + curChildren := []ResourceNode{} + + for _, c := range tree.Nodes { + if (kind == "" || kind == c.Kind) && c.hasInParents(tree, n) { + curChildren = append(curChildren, c) + } + } + + return curChildren +} + +func (n *ResourceNode) hasInParents(tree *ApplicationTree, p *ResourceNode) bool { + if len(n.ParentRefs) == 0 { + return false + } + + for _, curParentRef := range n.ParentRefs { + if curParentRef.IsEqual(p.ResourceRef) { + return true + } + + parentNode := tree.FindNode(curParentRef.Group, curParentRef.Kind, curParentRef.Namespace, curParentRef.Name) + if parentNode == nil { + continue + } + + parentResult := parentNode.hasInParents(tree, p) + if parentResult { + return true + } + } + + return false +} + // ResourceStatus holds the current sync and health status of a resource // TODO: describe members of this type type ResourceStatus struct { @@ -2970,6 +3021,8 @@ type KustomizeOptions struct { BuildOptions string `protobuf:"bytes,1,opt,name=buildOptions"` // BinaryPath holds optional path to kustomize binary BinaryPath string `protobuf:"bytes,2,opt,name=binaryPath"` + + SetNamespace bool `protobuf:"varint,3,opt,name=setNamespace"` } // ApplicationDestinationServiceAccount holds information about the service account to be impersonated for the application sync operation. @@ -3157,6 +3210,11 @@ func (condition *ApplicationCondition) IsError() bool { return strings.HasSuffix(condition.Type, "Error") } +// IsWarning returns true if a condition indicates an warning condition +func (condition *ApplicationCondition) IsWarning() bool { + return strings.HasSuffix(condition.Type, "Warning") +} + // Equals compares two instances of ApplicationSource and return true if instances are equal. func (source *ApplicationSource) Equals(other *ApplicationSource) bool { if source == nil && other == nil { diff --git a/pkg/apis/application/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/application/v1alpha1/zz_generated.deepcopy.go index 9faf5d3a73b00..8d7826a9427e7 100644 --- a/pkg/apis/application/v1alpha1/zz_generated.deepcopy.go +++ b/pkg/apis/application/v1alpha1/zz_generated.deepcopy.go @@ -3721,6 +3721,20 @@ func (in *ResourceNode) DeepCopyInto(out *ResourceNode) { in, out := &in.CreatedAt, &out.CreatedAt *out = (*in).DeepCopy() } + if in.Labels != nil { + in, out := &in.Labels, &out.Labels + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.Annotations != nil { + in, out := &in.Annotations, &out.Annotations + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } return } @@ -4359,6 +4373,11 @@ func (in *SyncOperation) DeepCopyInto(out *SyncOperation) { *out = make([]string, len(*in)) copy(*out, *in) } + if in.ChangeRevisions != nil { + in, out := &in.ChangeRevisions, &out.ChangeRevisions + *out = make([]string, len(*in)) + copy(*out, *in) + } return } diff --git a/pkg/client/clientset/versioned/typed/application/v1alpha1/mocks/AppProjectInterface.go b/pkg/client/clientset/versioned/typed/application/v1alpha1/mocks/AppProjectInterface.go index 05262975cf54c..005cc2f543811 100644 --- a/pkg/client/clientset/versioned/typed/application/v1alpha1/mocks/AppProjectInterface.go +++ b/pkg/client/clientset/versioned/typed/application/v1alpha1/mocks/AppProjectInterface.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.52.4. DO NOT EDIT. +// Code generated by mockery v2.43.2. DO NOT EDIT. package mocks diff --git a/pkg/codefresh/api_graphql_requests.go b/pkg/codefresh/api_graphql_requests.go new file mode 100644 index 0000000000000..b7e06ff617bec --- /dev/null +++ b/pkg/codefresh/api_graphql_requests.go @@ -0,0 +1,54 @@ +package codefresh + +import ( + "encoding/json" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +type CodefreshGraphQLRequests struct { + client CodefreshClientInterface +} + +type CodefreshGraphQLInterface interface { + GetPromotionTemplate(app *metav1.ObjectMeta) (*PromotionTemplate, error) +} + +// GetPromotionTemplate method to get application configuration +func (r *CodefreshGraphQLRequests) GetPromotionTemplate(app *metav1.ObjectMeta) (*PromotionTemplate, error) { + type ResponseData struct { + PromotionTemplateByRuntime PromotionTemplate `json:"promotionTemplateByRuntime"` + } + + query := GraphQLQuery{ + Query: ` + query ($applicationMetadata: Object!) { + promotionTemplateByRuntime(applicationMetadata: $applicationMetadata) { + versionSource { + file + jsonPath + } + } + } + `, + Variables: map[string]interface{}{ + "applicationMetadata": app, + }, + } + + responseJSON, err := r.client.SendGraphQL(query) + if err != nil { + return nil, err + } + + var responseData ResponseData + if err := json.Unmarshal(*responseJSON, &responseData); err != nil { + return nil, err + } + + return &responseData.PromotionTemplateByRuntime, nil +} + +func NewCodefreshGraphQLRequests(client CodefreshClientInterface) CodefreshGraphQLInterface { + return &CodefreshGraphQLRequests{client} +} diff --git a/pkg/codefresh/client.go b/pkg/codefresh/client.go new file mode 100644 index 0000000000000..0356ee5e7ccbf --- /dev/null +++ b/pkg/codefresh/client.go @@ -0,0 +1,182 @@ +package codefresh + +import ( + "bytes" + "compress/gzip" + "context" + "crypto/tls" + "crypto/x509" + "encoding/json" + "fmt" + "io" + "net/http" + "net/url" + "os" + "time" + + "github.com/pkg/errors" + log "github.com/sirupsen/logrus" + + "github.com/argoproj/argo-cd/v2/pkg/apiclient/events" +) + +type CodefreshConfig struct { + BaseURL string + AuthToken string + TlsInsecure bool + CaCertPath string + RuntimeVersion string +} + +type CodefreshClient struct { + cfConfig *CodefreshConfig + httpClient *http.Client +} + +type CodefreshClientInterface interface { + SendEvent(ctx context.Context, appName string, event *events.Event) error + SendGraphQL(query GraphQLQuery) (*json.RawMessage, error) +} + +// GraphQLQuery structure to form a GraphQL query +type GraphQLQuery struct { + Query string `json:"query"` + Variables map[string]interface{} `json:"variables"` +} + +func (c *CodefreshClient) SendEvent(ctx context.Context, appName string, event *events.Event) error { + return WithRetry(&DefaultBackoff, func() error { + url, err := url.JoinPath(c.cfConfig.BaseURL, "/2.0/api/events") + if err != nil { + return fmt.Errorf("failed to join URL: %w", err) + } + + log.Infof("Sending application event for %s", appName) + + wrappedPayload := map[string]json.RawMessage{ + "data": event.Payload, + } + + newPayloadBytes, err := json.Marshal(wrappedPayload) + if err != nil { + return err + } + + // Create a buffer to hold the compressed data + var buf bytes.Buffer + + // Create a gzip writer + gz := gzip.NewWriter(&buf) + defer gz.Close() + + // Write the data to the gzip writer + if _, err := gz.Write(newPayloadBytes); err != nil { + return err + } + if err := gz.Close(); err != nil { + return err + } + + req, err := http.NewRequestWithContext(ctx, http.MethodPost, url, io.NopCloser(&buf)) + if err != nil { + return err + } + + req.Header.Set("Content-Type", "application/json") + req.Header.Set("Content-Encoding", "gzip") + req.Header.Set("Authorization", c.cfConfig.AuthToken) + + res, err := c.httpClient.Do(req) + if err != nil { + return errors.Wrap(err, fmt.Sprintf("failed reporting to Codefresh, event: %s", string(event.Payload))) + } + defer res.Body.Close() + + isStatusOK := res.StatusCode >= 200 && res.StatusCode < 300 + if !isStatusOK { + b, _ := io.ReadAll(res.Body) + return errors.Errorf("failed reporting to Codefresh, got response: status code %d and body %s, original request body: %s", + res.StatusCode, string(b), string(event.Payload)) + } + + log.Infof("Application event for %s successfully sent", appName) + return nil + }) +} + +// sendGraphQLRequest function to send the GraphQL request and handle the response +func (c *CodefreshClient) SendGraphQL(query GraphQLQuery) (*json.RawMessage, error) { + queryJSON, err := json.Marshal(query) + if err != nil { + return nil, err + } + + req, err := http.NewRequest(http.MethodPost, c.cfConfig.BaseURL+"/2.0/api/graphql", bytes.NewBuffer(queryJSON)) + if err != nil { + return nil, err + } + req.Header.Set("Content-Type", "application/json") + req.Header.Set("Authorization", c.cfConfig.AuthToken) + + resp, err := c.httpClient.Do(req) + if err != nil { + return nil, err + } + if resp.StatusCode >= 400 { + return nil, errors.New(resp.Status) + } + defer resp.Body.Close() + + var responseStruct struct { + Data json.RawMessage `json:"data"` + } + if err := json.NewDecoder(resp.Body).Decode(&responseStruct); err != nil { + return nil, err + } + + return &responseStruct.Data, nil +} + +func NewCodefreshClient(cfConfig *CodefreshConfig) CodefreshClientInterface { + return &CodefreshClient{ + cfConfig: cfConfig, + httpClient: cfConfig.getHttpClient(), + } +} + +func (cfConfig *CodefreshConfig) getHttpClient() *http.Client { + httpClient := &http.Client{ + Timeout: 30 * time.Second, + } + + httpClient.Transport = &http.Transport{ + TLSClientConfig: cfConfig.getTlsConfig(), + } + + return httpClient +} + +func (cfConfig *CodefreshConfig) getTlsConfig() *tls.Config { + c := &tls.Config{} + + if cfConfig.TlsInsecure { + return &tls.Config{ + InsecureSkipVerify: true, + ClientAuth: 0, + } + } + + if cfConfig.CaCertPath != "" { + cert, err := os.ReadFile(cfConfig.CaCertPath) + if err != nil { + log.Fatal(err) + } + pool := x509.NewCertPool() + if ok := pool.AppendCertsFromPEM(cert); !ok { + log.Fatalf("unable to parse codefresh cert from path %s", cfConfig.CaCertPath) + } + c.RootCAs = pool + } + + return c +} diff --git a/pkg/codefresh/client_test.go b/pkg/codefresh/client_test.go new file mode 100644 index 0000000000000..33b0b06403ce7 --- /dev/null +++ b/pkg/codefresh/client_test.go @@ -0,0 +1,102 @@ +package codefresh + +import ( + "compress/gzip" + "context" + "io" + "net/http" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + + "github.com/argoproj/argo-cd/v2/pkg/apiclient/events" +) + +type MockRoundTripper struct { + mock.Mock +} + +func (r *MockRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) { + args := r.Called(req) + + if args.Error(1) != nil { + return nil, args.Error(1) + } + + return args.Get(0).(*http.Response), args.Error(1) +} + +func TestCodefreshClient_SendEvent(t *testing.T) { + tests := []struct { + name string + baseURL string + authToken string + payload []byte + wantErr string + beforeFn func(t *testing.T, rt *MockRoundTripper) + }{ + { + name: "should return nil when all is good", + baseURL: "http://some.host", + authToken: "some-token", + payload: []byte(`{"key": "value"}`), + beforeFn: func(t *testing.T, rt *MockRoundTripper) { + t.Helper() + rt.On("RoundTrip", mock.Anything).Run(func(args mock.Arguments) { + req := args.Get(0).(*http.Request) + assert.Equal(t, "POST", req.Method, "invalid request method") + assert.Equal(t, "http://some.host/2.0/api/events", req.URL.String(), "invalid request URL") + assert.Equal(t, "some-token", req.Header.Get("Authorization"), "missing or invalid Authorization header") + assert.Equal(t, "application/json", req.Header.Get("Content-Type"), "missing or invalid Content-Type header") + reader, err := gzip.NewReader(req.Body) + require.NoError(t, err, "failed to create gzip reader") + defer reader.Close() + body, err := io.ReadAll(reader) + require.NoError(t, err, "failed to read request body") + assert.JSONEq(t, `{"data":{"key":"value"}}`, string(body), "invalid request body") + }).Return(&http.Response{ + StatusCode: http.StatusOK, + }, nil) + }, + }, + { + name: "should create correct url when baseUrl ends with '/'", + baseURL: "http://some.host/", + authToken: "some-token", + payload: []byte(`{"key": "value"}`), + beforeFn: func(t *testing.T, rt *MockRoundTripper) { + t.Helper() + rt.On("RoundTrip", mock.Anything).Run(func(args mock.Arguments) { + req := args.Get(0).(*http.Request) + assert.Equal(t, "http://some.host/2.0/api/events", req.URL.String(), "invalid request URL") + }).Return(&http.Response{ + StatusCode: http.StatusOK, + }, nil) + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + mockRT := &MockRoundTripper{} + c := &CodefreshClient{ + cfConfig: &CodefreshConfig{ + BaseURL: tt.baseURL, + AuthToken: tt.authToken, + }, + httpClient: &http.Client{ + Transport: mockRT, + }, + } + event := &events.Event{ + Payload: tt.payload, + } + tt.beforeFn(t, mockRT) + if err := c.SendEvent(context.Background(), "appName", event); err != nil || tt.wantErr != "" { + assert.EqualError(t, err, tt.wantErr) + } + }) + } +} diff --git a/pkg/codefresh/types.go b/pkg/codefresh/types.go new file mode 100644 index 0000000000000..cd845ad1a609f --- /dev/null +++ b/pkg/codefresh/types.go @@ -0,0 +1,11 @@ +package codefresh + +// VersionSource structure for the versionSource field +type VersionSource struct { + File string `json:"file"` + JsonPath string `json:"jsonPath"` +} + +type PromotionTemplate struct { + VersionSource VersionSource `json:"versionSource"` +} diff --git a/pkg/codefresh/utils.go b/pkg/codefresh/utils.go new file mode 100644 index 0000000000000..7496ef5511012 --- /dev/null +++ b/pkg/codefresh/utils.go @@ -0,0 +1,151 @@ +package codefresh + +import ( + "fmt" + "strconv" + "time" + + "k8s.io/apimachinery/pkg/util/wait" +) + +// Backoff for an operation +type Backoff struct { + // The initial duration in nanoseconds or strings like "1s", "3m" + // +optional + Duration *Int64OrString `json:"duration,omitempty" protobuf:"bytes,1,opt,name=duration"` + // Duration is multiplied by factor each iteration + // +optional + Factor *Amount `json:"factor,omitempty" protobuf:"bytes,2,opt,name=factor"` + // The amount of jitter applied each iteration + // +optional + Jitter *Amount `json:"jitter,omitempty" protobuf:"bytes,3,opt,name=jitter"` + // Exit with error after this many steps + // +optional + Steps int32 `json:"steps,omitempty" protobuf:"varint,4,opt,name=steps"` +} + +// Amount represent a numeric amount. +type Amount struct { + Value []byte `json:"value" protobuf:"bytes,1,opt,name=value"` +} + +type Int64OrString struct { + Type Type `json:"type" protobuf:"varint,1,opt,name=type,casttype=Type"` + Int64Val int64 `json:"int64Val,omitempty" protobuf:"varint,2,opt,name=int64Val"` + StrVal string `json:"strVal,omitempty" protobuf:"bytes,3,opt,name=strVal"` +} + +// Type represents the stored type of Int64OrString. +type Type int64 + +const ( + Int64 Type = iota // The Int64OrString holds an int64. + String // The Int64OrString holds a string. +) + +func NewAmount(s string) Amount { + return Amount{Value: []byte(s)} +} + +// FromString creates an Int64OrString object with a string value. +func FromString(val string) Int64OrString { + return Int64OrString{Type: String, StrVal: val} +} + +// Int64Value returns the Int64Val if type Int64, or if +// it is a String, will attempt a conversion to int64, +// returning 0 if a parsing error occurs. +func (int64str *Int64OrString) Int64Value() int64 { + if int64str.Type == String { + i, _ := strconv.ParseInt(int64str.StrVal, 10, 64) + return i + } + return int64str.Int64Val +} + +var ( + defaultFactor = NewAmount("1.0") + defaultJitter = NewAmount("1") + defaultDuration = FromString("1s") + + DefaultBackoff = Backoff{ + Steps: 5, + Duration: &defaultDuration, + Factor: &defaultFactor, + Jitter: &defaultJitter, + } +) + +func (n *Amount) Float64() (float64, error) { + return strconv.ParseFloat(string(n.Value), 64) +} + +// Convert2WaitBackoff converts to a wait backoff option +func Convert2WaitBackoff(backoff *Backoff) (*wait.Backoff, error) { + result := wait.Backoff{} + + d := backoff.Duration + if d == nil { + d = &defaultDuration + } + if d.Type == Int64 { + result.Duration = time.Duration(d.Int64Value()) + } else { + parsedDuration, err := time.ParseDuration(d.StrVal) + if err != nil { + return nil, err + } + result.Duration = parsedDuration + } + + factor := backoff.Factor + if factor == nil { + factor = &defaultFactor + } + f, err := factor.Float64() + if err != nil { + return nil, fmt.Errorf("invalid factor, %w", err) + } + result.Factor = f + + jitter := backoff.Jitter + if jitter == nil { + jitter = &defaultJitter + } + j, err := jitter.Float64() + if err != nil { + return nil, fmt.Errorf("invalid jitter, %w", err) + } + result.Jitter = j + + if backoff.Steps > 0 { + result.Steps = backoff.GetSteps() + } else { + result.Steps = int(DefaultBackoff.Steps) + } + return &result, nil +} + +func (b Backoff) GetSteps() int { + return int(b.Steps) +} + +func WithRetry(backoff *Backoff, f func() error) error { + if backoff == nil { + backoff = &DefaultBackoff + } + b, err := Convert2WaitBackoff(backoff) + if err != nil { + return fmt.Errorf("invalid backoff configuration, %w", err) + } + _ = wait.ExponentialBackoff(*b, func() (bool, error) { + if err = f(); err != nil { + return false, nil + } + return true, nil + }) + if err != nil { + return fmt.Errorf("failed after retries: %w", err) + } + return nil +} diff --git a/pkg/sources_server_client/client.go b/pkg/sources_server_client/client.go new file mode 100644 index 0000000000000..ddc9083480194 --- /dev/null +++ b/pkg/sources_server_client/client.go @@ -0,0 +1,108 @@ +package sources_server_client + +import ( + "bytes" + "encoding/json" + "fmt" + "io" + "net/http" + netUrl "net/url" + + log "github.com/sirupsen/logrus" + + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" +) + +type VersionPayload struct { + App v1alpha1.Application `json:"app"` + Revision string `json:"revision"` +} + +type DependenciesMap struct { + Lock string `json:"helm/Chart.lock"` + Deps string `json:"helm/dependencies"` + Requirements string `json:"helm/requirements.yaml"` +} + +type AppVersionResult struct { + AppVersion string `json:"appVersion"` + Dependencies DependenciesMap `json:"dependencies"` +} + +type SourcesServerConfig struct { + BaseURL string +} + +type sourceServerClient struct { + clientConfig *SourcesServerConfig +} + +type SourceServerClientInteface interface { + GetAppVersion(app *v1alpha1.Application, revision *string) *AppVersionResult +} + +func (c *sourceServerClient) sendRequest(method, url string, payload interface{}) ([]byte, error) { + var requestBody []byte + var err error + if payload != nil { + requestBody, err = json.Marshal(payload) + if err != nil { + return nil, fmt.Errorf("error marshalling payload: %w", err) + } + } + + fullURL, err := netUrl.JoinPath(c.clientConfig.BaseURL, url) + if err != nil { + return nil, fmt.Errorf("error joining path: %w", err) + } + + req, err := http.NewRequest(method, fullURL, bytes.NewBuffer(requestBody)) + if err != nil { + return nil, fmt.Errorf("error creating request: %w", err) + } + + req.Header.Set("Content-Type", "application/json") + + client := &http.Client{} + resp, err := client.Do(req) + if err != nil { + return nil, fmt.Errorf("error making request: %w", err) + } + defer resp.Body.Close() + + if resp.StatusCode < 200 || resp.StatusCode >= 300 { + body, _ := io.ReadAll(resp.Body) + return nil, fmt.Errorf("server responded with status %d: %s", resp.StatusCode, string(body)) + } + + body, err := io.ReadAll(resp.Body) + if err != nil { + return nil, fmt.Errorf("error reading response body: %w", err) + } + + return body, nil +} + +func (c *sourceServerClient) GetAppVersion(app *v1alpha1.Application, revision *string) *AppVersionResult { + log.Infof("cfGetAppVersion. Sending request to sources-server for %s", app.Name) + appVersionResult, err := c.sendRequest("POST", "/getAppVersion", VersionPayload{App: *app, Revision: *revision}) + if err != nil { + log.Errorf("error getting app version: %v", err) + return nil + } + + var versionStruct AppVersionResult + err = json.Unmarshal(appVersionResult, &versionStruct) + if err != nil { + log.Errorf("error unmarshaling app version: %v", err) + return nil + } + + return &versionStruct +} + +func NewSourceServerClient(clientConfig *SourcesServerConfig) SourceServerClientInteface { + return &sourceServerClient{ + clientConfig: clientConfig, + } +} diff --git a/pkg/version_config_manager/version_config_manager.go b/pkg/version_config_manager/version_config_manager.go new file mode 100644 index 0000000000000..826b0585c6821 --- /dev/null +++ b/pkg/version_config_manager/version_config_manager.go @@ -0,0 +1,80 @@ +package version_config_manager + +import ( + log "github.com/sirupsen/logrus" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + "github.com/argoproj/argo-cd/v2/pkg/codefresh" + "github.com/argoproj/argo-cd/v2/reposerver/cache" +) + +type VersionConfig struct { + JsonPath string `json:"jsonPath"` + ResourceName string `json:"resourceName"` +} + +const ( + DefaultVersionSource = "Chart.yaml" + DefaultVersionPath = "$.appVersion" +) + +func (v *VersionConfigManager) GetVersionConfig(app *metav1.ObjectMeta) (*VersionConfig, error) { + var appConfig *codefresh.PromotionTemplate + + // Get from cache + appConfig, err := v.cache.GetCfAppConfig(app.Namespace, app.Name) + if err == nil { + log.Infof("CfAppConfig cache hit: '%s'", cache.CfAppConfigCacheKey(app.Namespace, app.Name)) + log.Infof("CfAppConfig. Use config from cache. File: %s, jsonPath: %s", appConfig.VersionSource.File, appConfig.VersionSource.JsonPath) + return &VersionConfig{ + JsonPath: appConfig.VersionSource.JsonPath, + ResourceName: appConfig.VersionSource.File, + }, nil + } + + if err != nil { + log.Errorf("CfAppConfig cache get error for '%s': %v", cache.CfAppConfigCacheKey(app.Namespace, app.Name), err) + } + + // Get from Codefresh API + appConfig, err = v.requests.GetPromotionTemplate(app) + if err != nil { + log.Infof("Failed to get application config from API: %v", err) + return nil, err + } + + if appConfig != nil { + log.Infof("CfAppConfig. Use config from API. File: %s, jsonPath: %s", appConfig.VersionSource.File, appConfig.VersionSource.JsonPath) + // Set to cache + err = v.cache.SetCfAppConfig(app.Namespace, app.Name, appConfig) + if err == nil { + log.Infof("CfAppConfig saved to cache hit: '%s'", cache.CfAppConfigCacheKey(app.Namespace, app.Name)) + } else { + log.Errorf("CfAppConfig cache set error for '%s': %v", cache.CfAppConfigCacheKey(app.Namespace, app.Name), err) + } + + return &VersionConfig{ + JsonPath: appConfig.VersionSource.JsonPath, + ResourceName: appConfig.VersionSource.File, + }, nil + } + + // Default value + log.Infof("Used default CfAppConfig for: '%s'", cache.CfAppConfigCacheKey(app.Namespace, app.Name)) + return &VersionConfig{ + JsonPath: DefaultVersionPath, + ResourceName: DefaultVersionSource, + }, nil +} + +type VersionConfigManager struct { + requests codefresh.CodefreshGraphQLInterface + cache *cache.Cache +} + +func NewVersionConfigManager(requests codefresh.CodefreshGraphQLInterface, cache *cache.Cache) *VersionConfigManager { + return &VersionConfigManager{ + requests, + cache, + } +} diff --git a/reposerver/apiclient/cf_repository.go b/reposerver/apiclient/cf_repository.go new file mode 100644 index 0000000000000..f060911b8cf43 --- /dev/null +++ b/reposerver/apiclient/cf_repository.go @@ -0,0 +1,9 @@ +package apiclient + +func (m *ManifestResponse) GetCompiledManifests() []string { + manifests := make([]string, len(m.Manifests)) + for i, m := range m.Manifests { + manifests[i] = m.CompiledManifest + } + return manifests +} diff --git a/reposerver/apiclient/mocks/RepoServerServiceClient.go b/reposerver/apiclient/mocks/RepoServerServiceClient.go index 056747e5b28be..4441ec3de2dd9 100644 --- a/reposerver/apiclient/mocks/RepoServerServiceClient.go +++ b/reposerver/apiclient/mocks/RepoServerServiceClient.go @@ -132,6 +132,43 @@ func (_m *RepoServerServiceClient) GetAppDetails(ctx context.Context, in *apicli return r0, r1 } +// GetChangeRevision provides a mock function with given fields: ctx, in, opts +func (_m *RepoServerServiceClient) GetChangeRevision(ctx context.Context, in *apiclient.ChangeRevisionRequest, opts ...grpc.CallOption) (*apiclient.ChangeRevisionResponse, error) { + _va := make([]interface{}, len(opts)) + for _i := range opts { + _va[_i] = opts[_i] + } + var _ca []interface{} + _ca = append(_ca, ctx, in) + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + if len(ret) == 0 { + panic("no return value specified for GetChangeRevision") + } + + var r0 *apiclient.ChangeRevisionResponse + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *apiclient.ChangeRevisionRequest, ...grpc.CallOption) (*apiclient.ChangeRevisionResponse, error)); ok { + return rf(ctx, in, opts...) + } + if rf, ok := ret.Get(0).(func(context.Context, *apiclient.ChangeRevisionRequest, ...grpc.CallOption) *apiclient.ChangeRevisionResponse); ok { + r0 = rf(ctx, in, opts...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*apiclient.ChangeRevisionResponse) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *apiclient.ChangeRevisionRequest, ...grpc.CallOption) error); ok { + r1 = rf(ctx, in, opts...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + // GetGitDirectories provides a mock function with given fields: ctx, in, opts func (_m *RepoServerServiceClient) GetGitDirectories(ctx context.Context, in *apiclient.GitDirectoriesRequest, opts ...grpc.CallOption) (*apiclient.GitDirectoriesResponse, error) { _va := make([]interface{}, len(opts)) diff --git a/reposerver/apiclient/repository.pb.go b/reposerver/apiclient/repository.pb.go index 34adb3bc07fdc..c068593d7a9cc 100644 --- a/reposerver/apiclient/repository.pb.go +++ b/reposerver/apiclient/repository.pb.go @@ -13,6 +13,8 @@ import ( status "google.golang.org/grpc/status" emptypb "google.golang.org/protobuf/types/known/emptypb" io "io" + _ "k8s.io/api/core/v1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" math "math" math_bits "math/bits" ) @@ -63,10 +65,11 @@ type ManifestRequest struct { // argocd.argoproj.io/manifest-generate-paths annotation value of the Application to allow optimize which resources propagated to cmpserver AnnotationManifestGeneratePaths string `protobuf:"bytes,26,opt,name=annotationManifestGeneratePaths,proto3" json:"annotationManifestGeneratePaths,omitempty"` // Holds instance installation id - InstallationID string `protobuf:"bytes,27,opt,name=installationID,proto3" json:"installationID,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + InstallationID string `protobuf:"bytes,27,opt,name=installationID,proto3" json:"installationID,omitempty"` + ApplicationMetadata *v1.ObjectMeta `protobuf:"bytes,28,opt,name=applicationMetadata,proto3" json:"applicationMetadata,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *ManifestRequest) Reset() { *m = ManifestRequest{} } @@ -270,6 +273,13 @@ func (m *ManifestRequest) GetInstallationID() string { return "" } +func (m *ManifestRequest) GetApplicationMetadata() *v1.ObjectMeta { + if m != nil { + return m.ApplicationMetadata + } + return nil +} + type ManifestRequestWithFiles struct { // Types that are valid to be assigned to Part: // *ManifestRequestWithFiles_Request @@ -701,17 +711,223 @@ func (m *ResolveRevisionResponse) GetAmbiguousRevision() string { return "" } +type Manifest struct { + // The processed manifest that needs to be applied to the cluster + CompiledManifest string `protobuf:"bytes,1,opt,name=compiledManifest,proto3" json:"compiledManifest,omitempty"` + // The pre-processed manifest (for example the kustomization.yaml + // when using kustmize or the values.yaml when using helm). + RawManifest string `protobuf:"bytes,2,opt,name=rawManifest,proto3" json:"rawManifest,omitempty"` + // The path of the raw manifest inside the repo + Path string `protobuf:"bytes,3,opt,name=path,proto3" json:"path,omitempty"` + // The line in the file where the object starts + Line int32 `protobuf:"varint,4,opt,name=line,proto3" json:"line,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Manifest) Reset() { *m = Manifest{} } +func (m *Manifest) String() string { return proto.CompactTextString(m) } +func (*Manifest) ProtoMessage() {} +func (*Manifest) Descriptor() ([]byte, []int) { + return fileDescriptor_dd8723cfcc820480, []int{8} +} +func (m *Manifest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Manifest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Manifest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *Manifest) XXX_Merge(src proto.Message) { + xxx_messageInfo_Manifest.Merge(m, src) +} +func (m *Manifest) XXX_Size() int { + return m.Size() +} +func (m *Manifest) XXX_DiscardUnknown() { + xxx_messageInfo_Manifest.DiscardUnknown(m) +} + +var xxx_messageInfo_Manifest proto.InternalMessageInfo + +func (m *Manifest) GetCompiledManifest() string { + if m != nil { + return m.CompiledManifest + } + return "" +} + +func (m *Manifest) GetRawManifest() string { + if m != nil { + return m.RawManifest + } + return "" +} + +func (m *Manifest) GetPath() string { + if m != nil { + return m.Path + } + return "" +} + +func (m *Manifest) GetLine() int32 { + if m != nil { + return m.Line + } + return 0 +} + +type Dependencies struct { + // Content of Chart.lock + Lock string `protobuf:"bytes,1,opt,name=lock,proto3" json:"lock,omitempty"` + // Content of Cart.yaml/dependencies + Deps string `protobuf:"bytes,2,opt,name=deps,proto3" json:"deps,omitempty"` + // Content of requirements.yaml + Requirements string `protobuf:"bytes,3,opt,name=requirements,proto3" json:"requirements,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Dependencies) Reset() { *m = Dependencies{} } +func (m *Dependencies) String() string { return proto.CompactTextString(m) } +func (*Dependencies) ProtoMessage() {} +func (*Dependencies) Descriptor() ([]byte, []int) { + return fileDescriptor_dd8723cfcc820480, []int{9} +} +func (m *Dependencies) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Dependencies) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Dependencies.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *Dependencies) XXX_Merge(src proto.Message) { + xxx_messageInfo_Dependencies.Merge(m, src) +} +func (m *Dependencies) XXX_Size() int { + return m.Size() +} +func (m *Dependencies) XXX_DiscardUnknown() { + xxx_messageInfo_Dependencies.DiscardUnknown(m) +} + +var xxx_messageInfo_Dependencies proto.InternalMessageInfo + +func (m *Dependencies) GetLock() string { + if m != nil { + return m.Lock + } + return "" +} + +func (m *Dependencies) GetDeps() string { + if m != nil { + return m.Deps + } + return "" +} + +func (m *Dependencies) GetRequirements() string { + if m != nil { + return m.Requirements + } + return "" +} + +type ApplicationVersions struct { + // Application version presented by single value + AppVersion string `protobuf:"bytes,1,opt,name=appVersion,proto3" json:"appVersion,omitempty"` + // Yaml content of dependencies + Dependencies *Dependencies `protobuf:"bytes,2,opt,name=dependencies,proto3" json:"dependencies,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ApplicationVersions) Reset() { *m = ApplicationVersions{} } +func (m *ApplicationVersions) String() string { return proto.CompactTextString(m) } +func (*ApplicationVersions) ProtoMessage() {} +func (*ApplicationVersions) Descriptor() ([]byte, []int) { + return fileDescriptor_dd8723cfcc820480, []int{10} +} +func (m *ApplicationVersions) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ApplicationVersions) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ApplicationVersions.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *ApplicationVersions) XXX_Merge(src proto.Message) { + xxx_messageInfo_ApplicationVersions.Merge(m, src) +} +func (m *ApplicationVersions) XXX_Size() int { + return m.Size() +} +func (m *ApplicationVersions) XXX_DiscardUnknown() { + xxx_messageInfo_ApplicationVersions.DiscardUnknown(m) +} + +var xxx_messageInfo_ApplicationVersions proto.InternalMessageInfo + +func (m *ApplicationVersions) GetAppVersion() string { + if m != nil { + return m.AppVersion + } + return "" +} + +func (m *ApplicationVersions) GetDependencies() *Dependencies { + if m != nil { + return m.Dependencies + } + return nil +} + type ManifestResponse struct { - Manifests []string `protobuf:"bytes,1,rep,name=manifests,proto3" json:"manifests,omitempty"` - Namespace string `protobuf:"bytes,2,opt,name=namespace,proto3" json:"namespace,omitempty"` - Server string `protobuf:"bytes,3,opt,name=server,proto3" json:"server,omitempty"` + Manifests []*Manifest `protobuf:"bytes,1,rep,name=manifests,proto3" json:"manifests,omitempty"` + Namespace string `protobuf:"bytes,2,opt,name=namespace,proto3" json:"namespace,omitempty"` + Server string `protobuf:"bytes,3,opt,name=server,proto3" json:"server,omitempty"` // resolved revision Revision string `protobuf:"bytes,4,opt,name=revision,proto3" json:"revision,omitempty"` SourceType string `protobuf:"bytes,6,opt,name=sourceType,proto3" json:"sourceType,omitempty"` // Raw response of git verify-commit operation (always the empty string for Helm) - VerifyResult string `protobuf:"bytes,7,opt,name=verifyResult,proto3" json:"verifyResult,omitempty"` + VerifyResult string `protobuf:"bytes,7,opt,name=verifyResult,proto3" json:"verifyResult,omitempty"` + CommitMessage string `protobuf:"bytes,8,opt,name=commitMessage,proto3" json:"commitMessage,omitempty"` + CommitAuthor string `protobuf:"bytes,9,opt,name=commitAuthor,proto3" json:"commitAuthor,omitempty"` + CommitDate *v1.Time `protobuf:"bytes,10,opt,name=commitDate,proto3" json:"commitDate,omitempty"` + // A version of the application and its dependencies + ApplicationVersions *ApplicationVersions `protobuf:"bytes,11,opt,name=applicationVersions,proto3" json:"applicationVersions,omitempty"` + // for multisourced apps will be [0,12,20], so this means that 0-11 - from first app source, 12-19 from second one, 20-x - third one + SourcesManifestsStartingIdx []int32 `protobuf:"varint,12,rep,packed,name=sourcesManifestsStartingIdx,proto3" json:"sourcesManifestsStartingIdx,omitempty"` // Commands is the list of commands used to hydrate the manifests - Commands []string `protobuf:"bytes,8,rep,name=commands,proto3" json:"commands,omitempty"` + Commands []string `protobuf:"bytes,13,rep,name=commands,proto3" json:"commands,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -721,7 +937,7 @@ func (m *ManifestResponse) Reset() { *m = ManifestResponse{} } func (m *ManifestResponse) String() string { return proto.CompactTextString(m) } func (*ManifestResponse) ProtoMessage() {} func (*ManifestResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_dd8723cfcc820480, []int{8} + return fileDescriptor_dd8723cfcc820480, []int{11} } func (m *ManifestResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -750,7 +966,7 @@ func (m *ManifestResponse) XXX_DiscardUnknown() { var xxx_messageInfo_ManifestResponse proto.InternalMessageInfo -func (m *ManifestResponse) GetManifests() []string { +func (m *ManifestResponse) GetManifests() []*Manifest { if m != nil { return m.Manifests } @@ -792,6 +1008,41 @@ func (m *ManifestResponse) GetVerifyResult() string { return "" } +func (m *ManifestResponse) GetCommitMessage() string { + if m != nil { + return m.CommitMessage + } + return "" +} + +func (m *ManifestResponse) GetCommitAuthor() string { + if m != nil { + return m.CommitAuthor + } + return "" +} + +func (m *ManifestResponse) GetCommitDate() *v1.Time { + if m != nil { + return m.CommitDate + } + return nil +} + +func (m *ManifestResponse) GetApplicationVersions() *ApplicationVersions { + if m != nil { + return m.ApplicationVersions + } + return nil +} + +func (m *ManifestResponse) GetSourcesManifestsStartingIdx() []int32 { + if m != nil { + return m.SourcesManifestsStartingIdx + } + return nil +} + func (m *ManifestResponse) GetCommands() []string { if m != nil { return m.Commands @@ -810,7 +1061,7 @@ func (m *ListRefsRequest) Reset() { *m = ListRefsRequest{} } func (m *ListRefsRequest) String() string { return proto.CompactTextString(m) } func (*ListRefsRequest) ProtoMessage() {} func (*ListRefsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_dd8723cfcc820480, []int{9} + return fileDescriptor_dd8723cfcc820480, []int{12} } func (m *ListRefsRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -859,7 +1110,7 @@ func (m *Refs) Reset() { *m = Refs{} } func (m *Refs) String() string { return proto.CompactTextString(m) } func (*Refs) ProtoMessage() {} func (*Refs) Descriptor() ([]byte, []int) { - return fileDescriptor_dd8723cfcc820480, []int{10} + return fileDescriptor_dd8723cfcc820480, []int{13} } func (m *Refs) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -916,7 +1167,7 @@ func (m *ListAppsRequest) Reset() { *m = ListAppsRequest{} } func (m *ListAppsRequest) String() string { return proto.CompactTextString(m) } func (*ListAppsRequest) ProtoMessage() {} func (*ListAppsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_dd8723cfcc820480, []int{11} + return fileDescriptor_dd8723cfcc820480, []int{14} } func (m *ListAppsRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -978,7 +1229,7 @@ func (m *AppList) Reset() { *m = AppList{} } func (m *AppList) String() string { return proto.CompactTextString(m) } func (*AppList) ProtoMessage() {} func (*AppList) Descriptor() ([]byte, []int) { - return fileDescriptor_dd8723cfcc820480, []int{12} + return fileDescriptor_dd8723cfcc820480, []int{15} } func (m *AppList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1025,7 +1276,7 @@ func (m *PluginInfo) Reset() { *m = PluginInfo{} } func (m *PluginInfo) String() string { return proto.CompactTextString(m) } func (*PluginInfo) ProtoMessage() {} func (*PluginInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_dd8723cfcc820480, []int{13} + return fileDescriptor_dd8723cfcc820480, []int{16} } func (m *PluginInfo) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1073,7 +1324,7 @@ func (m *PluginList) Reset() { *m = PluginList{} } func (m *PluginList) String() string { return proto.CompactTextString(m) } func (*PluginList) ProtoMessage() {} func (*PluginList) Descriptor() ([]byte, []int) { - return fileDescriptor_dd8723cfcc820480, []int{14} + return fileDescriptor_dd8723cfcc820480, []int{17} } func (m *PluginList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1131,7 +1382,7 @@ func (m *RepoServerAppDetailsQuery) Reset() { *m = RepoServerAppDetailsQ func (m *RepoServerAppDetailsQuery) String() string { return proto.CompactTextString(m) } func (*RepoServerAppDetailsQuery) ProtoMessage() {} func (*RepoServerAppDetailsQuery) Descriptor() ([]byte, []int) { - return fileDescriptor_dd8723cfcc820480, []int{15} + return fileDescriptor_dd8723cfcc820480, []int{18} } func (m *RepoServerAppDetailsQuery) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1253,7 +1504,7 @@ func (m *RepoAppDetailsResponse) Reset() { *m = RepoAppDetailsResponse{} func (m *RepoAppDetailsResponse) String() string { return proto.CompactTextString(m) } func (*RepoAppDetailsResponse) ProtoMessage() {} func (*RepoAppDetailsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_dd8723cfcc820480, []int{16} + return fileDescriptor_dd8723cfcc820480, []int{19} } func (m *RepoAppDetailsResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1333,7 +1584,7 @@ func (m *RepoServerRevisionMetadataRequest) Reset() { *m = RepoServerRev func (m *RepoServerRevisionMetadataRequest) String() string { return proto.CompactTextString(m) } func (*RepoServerRevisionMetadataRequest) ProtoMessage() {} func (*RepoServerRevisionMetadataRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_dd8723cfcc820480, []int{17} + return fileDescriptor_dd8723cfcc820480, []int{20} } func (m *RepoServerRevisionMetadataRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1399,7 +1650,7 @@ func (m *RepoServerRevisionChartDetailsRequest) Reset() { *m = RepoServe func (m *RepoServerRevisionChartDetailsRequest) String() string { return proto.CompactTextString(m) } func (*RepoServerRevisionChartDetailsRequest) ProtoMessage() {} func (*RepoServerRevisionChartDetailsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_dd8723cfcc820480, []int{18} + return fileDescriptor_dd8723cfcc820480, []int{21} } func (m *RepoServerRevisionChartDetailsRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1468,7 +1719,7 @@ func (m *HelmAppSpec) Reset() { *m = HelmAppSpec{} } func (m *HelmAppSpec) String() string { return proto.CompactTextString(m) } func (*HelmAppSpec) ProtoMessage() {} func (*HelmAppSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_dd8723cfcc820480, []int{19} + return fileDescriptor_dd8723cfcc820480, []int{22} } func (m *HelmAppSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1545,7 +1796,7 @@ func (m *KustomizeAppSpec) Reset() { *m = KustomizeAppSpec{} } func (m *KustomizeAppSpec) String() string { return proto.CompactTextString(m) } func (*KustomizeAppSpec) ProtoMessage() {} func (*KustomizeAppSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_dd8723cfcc820480, []int{20} + return fileDescriptor_dd8723cfcc820480, []int{23} } func (m *KustomizeAppSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1592,7 +1843,7 @@ func (m *DirectoryAppSpec) Reset() { *m = DirectoryAppSpec{} } func (m *DirectoryAppSpec) String() string { return proto.CompactTextString(m) } func (*DirectoryAppSpec) ProtoMessage() {} func (*DirectoryAppSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_dd8723cfcc820480, []int{21} + return fileDescriptor_dd8723cfcc820480, []int{24} } func (m *DirectoryAppSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1652,7 +1903,7 @@ func (m *ParameterAnnouncement) Reset() { *m = ParameterAnnouncement{} } func (m *ParameterAnnouncement) String() string { return proto.CompactTextString(m) } func (*ParameterAnnouncement) ProtoMessage() {} func (*ParameterAnnouncement) Descriptor() ([]byte, []int) { - return fileDescriptor_dd8723cfcc820480, []int{22} + return fileDescriptor_dd8723cfcc820480, []int{25} } func (m *ParameterAnnouncement) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1756,7 +2007,7 @@ func (m *PluginAppSpec) Reset() { *m = PluginAppSpec{} } func (m *PluginAppSpec) String() string { return proto.CompactTextString(m) } func (*PluginAppSpec) ProtoMessage() {} func (*PluginAppSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_dd8723cfcc820480, []int{23} + return fileDescriptor_dd8723cfcc820480, []int{26} } func (m *PluginAppSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1803,7 +2054,7 @@ func (m *HelmChartsRequest) Reset() { *m = HelmChartsRequest{} } func (m *HelmChartsRequest) String() string { return proto.CompactTextString(m) } func (*HelmChartsRequest) ProtoMessage() {} func (*HelmChartsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_dd8723cfcc820480, []int{24} + return fileDescriptor_dd8723cfcc820480, []int{27} } func (m *HelmChartsRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1851,7 +2102,7 @@ func (m *HelmChart) Reset() { *m = HelmChart{} } func (m *HelmChart) String() string { return proto.CompactTextString(m) } func (*HelmChart) ProtoMessage() {} func (*HelmChart) Descriptor() ([]byte, []int) { - return fileDescriptor_dd8723cfcc820480, []int{25} + return fileDescriptor_dd8723cfcc820480, []int{28} } func (m *HelmChart) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1905,7 +2156,7 @@ func (m *HelmChartsResponse) Reset() { *m = HelmChartsResponse{} } func (m *HelmChartsResponse) String() string { return proto.CompactTextString(m) } func (*HelmChartsResponse) ProtoMessage() {} func (*HelmChartsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_dd8723cfcc820480, []int{26} + return fileDescriptor_dd8723cfcc820480, []int{29} } func (m *HelmChartsResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1958,7 +2209,7 @@ func (m *GitFilesRequest) Reset() { *m = GitFilesRequest{} } func (m *GitFilesRequest) String() string { return proto.CompactTextString(m) } func (*GitFilesRequest) ProtoMessage() {} func (*GitFilesRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_dd8723cfcc820480, []int{27} + return fileDescriptor_dd8723cfcc820480, []int{30} } func (m *GitFilesRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2048,7 +2299,7 @@ func (m *GitFilesResponse) Reset() { *m = GitFilesResponse{} } func (m *GitFilesResponse) String() string { return proto.CompactTextString(m) } func (*GitFilesResponse) ProtoMessage() {} func (*GitFilesResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_dd8723cfcc820480, []int{28} + return fileDescriptor_dd8723cfcc820480, []int{31} } func (m *GitFilesResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2099,7 +2350,7 @@ func (m *GitDirectoriesRequest) Reset() { *m = GitDirectoriesRequest{} } func (m *GitDirectoriesRequest) String() string { return proto.CompactTextString(m) } func (*GitDirectoriesRequest) ProtoMessage() {} func (*GitDirectoriesRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_dd8723cfcc820480, []int{29} + return fileDescriptor_dd8723cfcc820480, []int{32} } func (m *GitDirectoriesRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2175,7 +2426,7 @@ func (m *GitDirectoriesResponse) Reset() { *m = GitDirectoriesResponse{} func (m *GitDirectoriesResponse) String() string { return proto.CompactTextString(m) } func (*GitDirectoriesResponse) ProtoMessage() {} func (*GitDirectoriesResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_dd8723cfcc820480, []int{30} + return fileDescriptor_dd8723cfcc820480, []int{33} } func (m *GitDirectoriesResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2236,7 +2487,7 @@ func (m *UpdateRevisionForPathsRequest) Reset() { *m = UpdateRevisionFor func (m *UpdateRevisionForPathsRequest) String() string { return proto.CompactTextString(m) } func (*UpdateRevisionForPathsRequest) ProtoMessage() {} func (*UpdateRevisionForPathsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_dd8723cfcc820480, []int{31} + return fileDescriptor_dd8723cfcc820480, []int{34} } func (m *UpdateRevisionForPathsRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2385,7 +2636,7 @@ func (m *UpdateRevisionForPathsResponse) Reset() { *m = UpdateRevisionFo func (m *UpdateRevisionForPathsResponse) String() string { return proto.CompactTextString(m) } func (*UpdateRevisionForPathsResponse) ProtoMessage() {} func (*UpdateRevisionForPathsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_dd8723cfcc820480, []int{32} + return fileDescriptor_dd8723cfcc820480, []int{35} } func (m *UpdateRevisionForPathsResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2428,211 +2679,373 @@ func (m *UpdateRevisionForPathsResponse) GetRevision() string { return "" } -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") - proto.RegisterType((*TestRepositoryRequest)(nil), "repository.TestRepositoryRequest") - proto.RegisterType((*TestRepositoryResponse)(nil), "repository.TestRepositoryResponse") - proto.RegisterType((*ResolveRevisionRequest)(nil), "repository.ResolveRevisionRequest") - proto.RegisterType((*ResolveRevisionResponse)(nil), "repository.ResolveRevisionResponse") - proto.RegisterType((*ManifestResponse)(nil), "repository.ManifestResponse") - proto.RegisterType((*ListRefsRequest)(nil), "repository.ListRefsRequest") - proto.RegisterType((*Refs)(nil), "repository.Refs") - proto.RegisterType((*ListAppsRequest)(nil), "repository.ListAppsRequest") - proto.RegisterMapType((map[string]bool)(nil), "repository.ListAppsRequest.EnabledSourceTypesEntry") - proto.RegisterType((*AppList)(nil), "repository.AppList") - proto.RegisterMapType((map[string]string)(nil), "repository.AppList.AppsEntry") - proto.RegisterType((*PluginInfo)(nil), "repository.PluginInfo") - 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((*RepoServerRevisionChartDetailsRequest)(nil), "repository.RepoServerRevisionChartDetailsRequest") - proto.RegisterType((*HelmAppSpec)(nil), "repository.HelmAppSpec") - proto.RegisterType((*KustomizeAppSpec)(nil), "repository.KustomizeAppSpec") - proto.RegisterType((*DirectoryAppSpec)(nil), "repository.DirectoryAppSpec") - proto.RegisterType((*ParameterAnnouncement)(nil), "repository.ParameterAnnouncement") - proto.RegisterMapType((map[string]string)(nil), "repository.ParameterAnnouncement.MapEntry") - proto.RegisterType((*PluginAppSpec)(nil), "repository.PluginAppSpec") - proto.RegisterType((*HelmChartsRequest)(nil), "repository.HelmChartsRequest") - proto.RegisterType((*HelmChart)(nil), "repository.HelmChart") - proto.RegisterType((*HelmChartsResponse)(nil), "repository.HelmChartsResponse") - proto.RegisterType((*GitFilesRequest)(nil), "repository.GitFilesRequest") - proto.RegisterType((*GitFilesResponse)(nil), "repository.GitFilesResponse") - proto.RegisterMapType((map[string][]byte)(nil), "repository.GitFilesResponse.MapEntry") - proto.RegisterType((*GitDirectoriesRequest)(nil), "repository.GitDirectoriesRequest") - proto.RegisterType((*GitDirectoriesResponse)(nil), "repository.GitDirectoriesResponse") - proto.RegisterType((*UpdateRevisionForPathsRequest)(nil), "repository.UpdateRevisionForPathsRequest") - proto.RegisterMapType((map[string]*v1alpha1.RefTarget)(nil), "repository.UpdateRevisionForPathsRequest.RefSourcesEntry") - proto.RegisterType((*UpdateRevisionForPathsResponse)(nil), "repository.UpdateRevisionForPathsResponse") +type ChangeRevisionRequest struct { + AppName string `protobuf:"bytes,1,opt,name=appName,proto3" json:"appName,omitempty"` + Namespace string `protobuf:"bytes,2,opt,name=namespace,proto3" json:"namespace,omitempty"` + CurrentRevision string `protobuf:"bytes,3,opt,name=currentRevision,proto3" json:"currentRevision,omitempty"` + PreviousRevision string `protobuf:"bytes,4,opt,name=previousRevision,proto3" json:"previousRevision,omitempty"` + Paths []string `protobuf:"bytes,5,rep,name=paths,proto3" json:"paths,omitempty"` + Repo *v1alpha1.Repository `protobuf:"bytes,6,opt,name=repo,proto3" json:"repo,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } -func init() { - proto.RegisterFile("reposerver/repository/repository.proto", fileDescriptor_dd8723cfcc820480) +func (m *ChangeRevisionRequest) Reset() { *m = ChangeRevisionRequest{} } +func (m *ChangeRevisionRequest) String() string { return proto.CompactTextString(m) } +func (*ChangeRevisionRequest) ProtoMessage() {} +func (*ChangeRevisionRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_dd8723cfcc820480, []int{36} } - -var fileDescriptor_dd8723cfcc820480 = []byte{ - // 2376 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x1a, 0x4d, 0x73, 0x1c, 0x47, - 0x55, 0xfb, 0x25, 0xed, 0x3e, 0x59, 0x5f, 0x6d, 0x5b, 0x1e, 0xaf, 0x6d, 0xa1, 0x0c, 0xd8, 0xe5, - 0xd8, 0xc9, 0xaa, 0x2c, 0x57, 0x62, 0x70, 0x42, 0x28, 0x45, 0xb6, 0x25, 0xc7, 0x96, 0x2d, 0xc6, - 0x4e, 0x28, 0x83, 0x81, 0xea, 0x9d, 0x6d, 0xed, 0x76, 0x34, 0x1f, 0xed, 0x99, 0x1e, 0x05, 0xb9, - 0x8a, 0x0b, 0x50, 0x5c, 0xb8, 0x73, 0xe0, 0xca, 0x6f, 0xa0, 0x38, 0x72, 0xa0, 0x28, 0x38, 0x52, - 0x5c, 0xb8, 0x50, 0x05, 0xe5, 0x5f, 0x42, 0xf5, 0xc7, 0x7c, 0xee, 0xec, 0x4a, 0x61, 0x6d, 0x05, - 0xb8, 0x48, 0xd3, 0xaf, 0x5f, 0xbf, 0xf7, 0xfa, 0x7d, 0xf5, 0x7b, 0xdd, 0x0b, 0x57, 0x02, 0xc2, - 0xfc, 0x90, 0x04, 0x07, 0x24, 0x58, 0x93, 0x9f, 0x94, 0xfb, 0xc1, 0x61, 0xe6, 0xb3, 0xc3, 0x02, - 0x9f, 0xfb, 0x08, 0x52, 0x48, 0xfb, 0x61, 0x9f, 0xf2, 0x41, 0xd4, 0xed, 0xd8, 0xbe, 0xbb, 0x86, - 0x83, 0xbe, 0xcf, 0x02, 0xff, 0x73, 0xf9, 0xf1, 0xae, 0xdd, 0x5b, 0x3b, 0x58, 0x5f, 0x63, 0xfb, - 0xfd, 0x35, 0xcc, 0x68, 0xb8, 0x86, 0x19, 0x73, 0xa8, 0x8d, 0x39, 0xf5, 0xbd, 0xb5, 0x83, 0x1b, - 0xd8, 0x61, 0x03, 0x7c, 0x63, 0xad, 0x4f, 0x3c, 0x12, 0x60, 0x4e, 0x7a, 0x8a, 0x72, 0xfb, 0x42, - 0xdf, 0xf7, 0xfb, 0x0e, 0x59, 0x93, 0xa3, 0x6e, 0xb4, 0xb7, 0x46, 0x5c, 0xc6, 0x35, 0x5b, 0xf3, - 0x1f, 0x73, 0xb0, 0xb0, 0x83, 0x3d, 0xba, 0x47, 0x42, 0x6e, 0x91, 0x17, 0x11, 0x09, 0x39, 0x7a, - 0x0e, 0x75, 0x21, 0x8c, 0x51, 0x59, 0xad, 0x5c, 0x9d, 0x5d, 0xdf, 0xee, 0xa4, 0xd2, 0x74, 0x62, - 0x69, 0xe4, 0xc7, 0x8f, 0xed, 0x5e, 0xe7, 0x60, 0xbd, 0xc3, 0xf6, 0xfb, 0x1d, 0x21, 0x4d, 0x27, - 0x23, 0x4d, 0x27, 0x96, 0xa6, 0x63, 0x25, 0xdb, 0xb2, 0x24, 0x55, 0xd4, 0x86, 0x66, 0x40, 0x0e, - 0x68, 0x48, 0x7d, 0xcf, 0xa8, 0xae, 0x56, 0xae, 0xb6, 0xac, 0x64, 0x8c, 0x0c, 0x98, 0xf1, 0xfc, - 0x4d, 0x6c, 0x0f, 0x88, 0x51, 0x5b, 0xad, 0x5c, 0x6d, 0x5a, 0xf1, 0x10, 0xad, 0xc2, 0x2c, 0x66, - 0xec, 0x21, 0xee, 0x12, 0xe7, 0x01, 0x39, 0x34, 0xea, 0x72, 0x61, 0x16, 0x24, 0xd6, 0x62, 0xc6, - 0x1e, 0x61, 0x97, 0x18, 0x0d, 0x39, 0x1b, 0x0f, 0xd1, 0x45, 0x68, 0x79, 0xd8, 0x25, 0x21, 0xc3, - 0x36, 0x31, 0x9a, 0x72, 0x2e, 0x05, 0xa0, 0x9f, 0xc2, 0x52, 0x46, 0xf0, 0x27, 0x7e, 0x14, 0xd8, - 0xc4, 0x00, 0xb9, 0xf5, 0xc7, 0x93, 0x6d, 0x7d, 0xa3, 0x48, 0xd6, 0x1a, 0xe6, 0x84, 0x7e, 0x04, - 0x0d, 0x69, 0x79, 0x63, 0x76, 0xb5, 0xf6, 0x5a, 0xb5, 0xad, 0xc8, 0x22, 0x0f, 0x66, 0x98, 0x13, - 0xf5, 0xa9, 0x17, 0x1a, 0xa7, 0x24, 0x87, 0xa7, 0x93, 0x71, 0xd8, 0xf4, 0xbd, 0x3d, 0xda, 0xdf, - 0xc1, 0x1e, 0xee, 0x13, 0x97, 0x78, 0x7c, 0x57, 0x12, 0xb7, 0x62, 0x26, 0xe8, 0x25, 0x2c, 0xee, - 0x47, 0x21, 0xf7, 0x5d, 0xfa, 0x92, 0x3c, 0x66, 0x62, 0x6d, 0x68, 0xcc, 0x49, 0x6d, 0x3e, 0x9a, - 0x8c, 0xf1, 0x83, 0x02, 0x55, 0x6b, 0x88, 0x8f, 0x70, 0x92, 0xfd, 0xa8, 0x4b, 0x3e, 0x23, 0x81, - 0xf4, 0xae, 0x79, 0xe5, 0x24, 0x19, 0x90, 0x72, 0x23, 0xaa, 0x47, 0xa1, 0xb1, 0xb0, 0x5a, 0x53, - 0x6e, 0x94, 0x80, 0xd0, 0x55, 0x58, 0x38, 0x20, 0x01, 0xdd, 0x3b, 0x7c, 0x42, 0xfb, 0x1e, 0xe6, - 0x51, 0x40, 0x8c, 0x45, 0xe9, 0x8a, 0x45, 0x30, 0x72, 0x61, 0x6e, 0x40, 0x1c, 0x57, 0xa8, 0x7c, - 0x33, 0x20, 0xbd, 0xd0, 0x58, 0x92, 0xfa, 0xdd, 0x9a, 0xdc, 0x82, 0x92, 0x9c, 0x95, 0xa7, 0x2e, - 0x04, 0xf3, 0x7c, 0x4b, 0x47, 0x8a, 0x8a, 0x11, 0xa4, 0x04, 0x2b, 0x80, 0xd1, 0x15, 0x98, 0xe7, - 0x01, 0xb6, 0xf7, 0xa9, 0xd7, 0xdf, 0x21, 0x7c, 0xe0, 0xf7, 0x8c, 0xd3, 0x52, 0x13, 0x05, 0x28, - 0xb2, 0x01, 0x11, 0x0f, 0x77, 0x1d, 0xd2, 0x53, 0xbe, 0xf8, 0xf4, 0x90, 0x91, 0xd0, 0x38, 0x23, - 0x77, 0x71, 0xb3, 0x93, 0xc9, 0x50, 0x85, 0x04, 0xd1, 0xb9, 0x3b, 0xb4, 0xea, 0xae, 0xc7, 0x83, - 0x43, 0xab, 0x84, 0x1c, 0xda, 0x87, 0x59, 0xb1, 0x8f, 0xd8, 0x15, 0xce, 0x4a, 0x57, 0xb8, 0x3f, - 0x99, 0x8e, 0xb6, 0x53, 0x82, 0x56, 0x96, 0x3a, 0xea, 0x00, 0x1a, 0xe0, 0x70, 0x27, 0x72, 0x38, - 0x65, 0x0e, 0x51, 0x62, 0x84, 0xc6, 0xb2, 0x54, 0x53, 0xc9, 0x0c, 0x7a, 0x00, 0x10, 0x90, 0xbd, - 0x18, 0xef, 0x9c, 0xdc, 0xf9, 0xf5, 0x71, 0x3b, 0xb7, 0x12, 0x6c, 0xb5, 0xe3, 0xcc, 0x72, 0xc1, - 0x5c, 0x6c, 0x83, 0xd8, 0x5c, 0x47, 0xbb, 0x0c, 0x6b, 0x43, 0xba, 0x58, 0xc9, 0x8c, 0xf0, 0x45, - 0x0d, 0x95, 0x49, 0xeb, 0xbc, 0xf2, 0xd6, 0x0c, 0x08, 0x6d, 0xc3, 0xd7, 0xb0, 0xe7, 0xf9, 0x5c, - 0x6e, 0x3f, 0x16, 0x65, 0x4b, 0xa7, 0xf7, 0x5d, 0xcc, 0x07, 0xa1, 0xd1, 0x96, 0xab, 0x8e, 0x42, - 0x13, 0x2e, 0x41, 0xbd, 0x90, 0x63, 0xc7, 0x91, 0x48, 0xf7, 0xef, 0x18, 0x17, 0x94, 0x4b, 0xe4, - 0xa1, 0xed, 0xbb, 0x70, 0x6e, 0x84, 0x71, 0xd1, 0x22, 0xd4, 0xf6, 0xc9, 0xa1, 0x3c, 0x14, 0x5a, - 0x96, 0xf8, 0x44, 0x67, 0xa0, 0x71, 0x80, 0x9d, 0x88, 0xc8, 0x34, 0xde, 0xb4, 0xd4, 0xe0, 0x76, - 0xf5, 0x9b, 0x95, 0xf6, 0x2f, 0x2b, 0xb0, 0x50, 0x50, 0x55, 0xc9, 0xfa, 0x1f, 0x66, 0xd7, 0xbf, - 0x86, 0xc0, 0xd9, 0x7b, 0x8a, 0x83, 0x3e, 0xe1, 0x19, 0x41, 0xcc, 0xbf, 0x55, 0xc0, 0x28, 0xd8, - 0xf0, 0x7b, 0x94, 0x0f, 0xee, 0x51, 0x87, 0x84, 0xe8, 0x16, 0xcc, 0x04, 0x0a, 0xa6, 0x8f, 0xba, - 0x0b, 0x63, 0x4c, 0xbf, 0x3d, 0x65, 0xc5, 0xd8, 0xe8, 0x23, 0x68, 0xba, 0x84, 0xe3, 0x1e, 0xe6, - 0x58, 0xcb, 0xbe, 0x5a, 0xb6, 0x52, 0x70, 0xd9, 0xd1, 0x78, 0xdb, 0x53, 0x56, 0xb2, 0x06, 0xbd, - 0x07, 0x0d, 0x7b, 0x10, 0x79, 0xfb, 0xf2, 0x90, 0x9b, 0x5d, 0xbf, 0x34, 0x6a, 0xf1, 0xa6, 0x40, - 0xda, 0x9e, 0xb2, 0x14, 0xf6, 0xc7, 0xd3, 0x50, 0x67, 0x38, 0xe0, 0xe6, 0x3d, 0x38, 0x53, 0xc6, - 0x42, 0x9c, 0xac, 0xf6, 0x80, 0xd8, 0xfb, 0x61, 0xe4, 0x6a, 0x35, 0x27, 0x63, 0x84, 0xa0, 0x1e, - 0xd2, 0x97, 0x4a, 0xd5, 0x35, 0x4b, 0x7e, 0x9b, 0x6f, 0xc3, 0xd2, 0x10, 0x37, 0x61, 0x54, 0x25, - 0x9b, 0xa0, 0x70, 0x4a, 0xb3, 0x36, 0x23, 0x38, 0xfb, 0x54, 0xea, 0x22, 0x39, 0x5e, 0x4e, 0xa2, - 0x56, 0x30, 0xb7, 0x61, 0xb9, 0xc8, 0x36, 0x64, 0xbe, 0x17, 0x12, 0x11, 0x6c, 0x32, 0x1f, 0x53, - 0xd2, 0x4b, 0x67, 0xa5, 0x14, 0x4d, 0xab, 0x64, 0xc6, 0xfc, 0x6d, 0x15, 0x96, 0x2d, 0x12, 0xfa, - 0xce, 0x01, 0x89, 0x93, 0xe5, 0xc9, 0x94, 0x3b, 0x3f, 0x80, 0x1a, 0x66, 0x4c, 0xbb, 0xc9, 0xfd, - 0xd7, 0x56, 0x50, 0x58, 0x82, 0x2a, 0x7a, 0x07, 0x96, 0xb0, 0xdb, 0xa5, 0xfd, 0xc8, 0x8f, 0xc2, - 0x78, 0x5b, 0xd2, 0xa9, 0x5a, 0xd6, 0xf0, 0x84, 0x48, 0x38, 0xa1, 0x8c, 0xc8, 0xfb, 0x5e, 0x8f, - 0xfc, 0x44, 0xd6, 0x50, 0x35, 0x2b, 0x0b, 0x32, 0x6d, 0x38, 0x37, 0xa4, 0x24, 0xad, 0xf0, 0x6c, - 0xd9, 0x56, 0x29, 0x94, 0x6d, 0xa5, 0x62, 0x54, 0x47, 0x88, 0x61, 0xbe, 0xaa, 0xc0, 0x62, 0x1a, - 0x5c, 0x9a, 0xfc, 0x45, 0x68, 0xb9, 0x1a, 0x16, 0x1a, 0x15, 0x99, 0x33, 0x53, 0x40, 0xbe, 0x82, - 0xab, 0x16, 0x2b, 0xb8, 0x65, 0x98, 0x56, 0x05, 0xb6, 0xde, 0xba, 0x1e, 0xe5, 0x44, 0xae, 0x17, - 0x44, 0x5e, 0x01, 0x08, 0x93, 0x0c, 0x67, 0x4c, 0xcb, 0xd9, 0x0c, 0x04, 0x99, 0x70, 0x4a, 0x9d, - 0xf7, 0x16, 0x09, 0x23, 0x87, 0x1b, 0x33, 0x12, 0x23, 0x07, 0x93, 0xf1, 0xe6, 0xbb, 0x2e, 0xf6, - 0x7a, 0xa1, 0xd1, 0x94, 0x22, 0x27, 0x63, 0xd3, 0x87, 0x85, 0x87, 0x54, 0xec, 0x6f, 0x2f, 0x3c, - 0x99, 0x50, 0x79, 0x1f, 0xea, 0x82, 0x99, 0x10, 0xaa, 0x1b, 0x60, 0xcf, 0x1e, 0x90, 0x58, 0x8f, - 0xc9, 0x58, 0x24, 0x01, 0x8e, 0xfb, 0xa1, 0x51, 0x95, 0x70, 0xf9, 0x6d, 0xfe, 0xbe, 0xaa, 0x24, - 0xdd, 0x60, 0x2c, 0xfc, 0xea, 0x1b, 0x80, 0xf2, 0x92, 0xa4, 0x36, 0x5c, 0x92, 0x14, 0x44, 0xfe, - 0x32, 0x25, 0xc9, 0x6b, 0x3a, 0xe4, 0xcc, 0x08, 0x66, 0x36, 0x18, 0x13, 0x82, 0xa0, 0x1b, 0x50, - 0xc7, 0x8c, 0x29, 0x85, 0x17, 0xf2, 0xb9, 0x46, 0x11, 0xff, 0xb5, 0x48, 0x12, 0xb5, 0x7d, 0x0b, - 0x5a, 0x09, 0xe8, 0x28, 0xb6, 0xad, 0x2c, 0xdb, 0x55, 0x00, 0x55, 0x73, 0xdf, 0xf7, 0xf6, 0x7c, - 0x61, 0x52, 0x11, 0x08, 0x7a, 0xa9, 0xfc, 0x36, 0x6f, 0xc7, 0x18, 0x52, 0xb6, 0x77, 0xa0, 0x41, - 0x39, 0x71, 0x63, 0xe1, 0x96, 0xb3, 0xc2, 0xa5, 0x84, 0x2c, 0x85, 0x64, 0xfe, 0xb9, 0x09, 0xe7, - 0x85, 0xc5, 0x9e, 0xc8, 0x10, 0xda, 0x60, 0xec, 0x0e, 0xe1, 0x98, 0x3a, 0xe1, 0x77, 0x23, 0x12, - 0x1c, 0xbe, 0x61, 0xc7, 0xe8, 0xc3, 0xb4, 0x8a, 0x40, 0x9d, 0x2d, 0x5f, 0x7b, 0xfb, 0xa5, 0xc9, - 0xa7, 0x3d, 0x57, 0xed, 0xcd, 0xf4, 0x5c, 0x65, 0x3d, 0x50, 0xfd, 0x84, 0x7a, 0xa0, 0xd1, 0x6d, - 0x70, 0xa6, 0xb9, 0x9e, 0xce, 0x37, 0xd7, 0x25, 0xad, 0xc5, 0xcc, 0x71, 0x5b, 0x8b, 0x66, 0x69, - 0x6b, 0xe1, 0x96, 0xc6, 0x71, 0x4b, 0xaa, 0xfb, 0xdb, 0x59, 0x0f, 0x1c, 0xe9, 0x6b, 0x93, 0x34, - 0x19, 0xf0, 0x46, 0x9b, 0x8c, 0x4f, 0x73, 0x4d, 0x83, 0x6a, 0xdb, 0xdf, 0x3b, 0xde, 0x9e, 0xc6, - 0xb4, 0x0f, 0xff, 0x77, 0xa5, 0xf7, 0x2f, 0x64, 0xc5, 0xc5, 0xfc, 0x54, 0x07, 0xc9, 0x61, 0x2f, - 0xce, 0x21, 0x71, 0xec, 0xea, 0xa4, 0x25, 0xbe, 0xd1, 0x75, 0xa8, 0x0b, 0x25, 0xeb, 0x92, 0xf8, - 0x5c, 0x56, 0x9f, 0xc2, 0x12, 0x1b, 0x8c, 0x3d, 0x61, 0xc4, 0xb6, 0x24, 0x12, 0xba, 0x0d, 0xad, - 0xc4, 0xf1, 0x75, 0x64, 0x5d, 0xcc, 0xae, 0x48, 0xe2, 0x24, 0x5e, 0x96, 0xa2, 0x8b, 0xb5, 0x3d, - 0x1a, 0x10, 0x5b, 0x16, 0x8c, 0x8d, 0xe1, 0xb5, 0x77, 0xe2, 0xc9, 0x64, 0x6d, 0x82, 0x8e, 0x6e, - 0xc0, 0xb4, 0xba, 0xe7, 0x90, 0x11, 0x34, 0xbb, 0x7e, 0x7e, 0x38, 0x99, 0xc6, 0xab, 0x34, 0xa2, - 0xf9, 0xa7, 0x0a, 0xbc, 0x95, 0x3a, 0x44, 0x1c, 0x4d, 0x71, 0xcd, 0xfe, 0xd5, 0x9f, 0xb8, 0x57, - 0x60, 0x5e, 0x36, 0x09, 0xe9, 0x75, 0x87, 0xba, 0x79, 0x2b, 0x40, 0xcd, 0xdf, 0x55, 0xe0, 0xf2, - 0xf0, 0x3e, 0x36, 0x07, 0x38, 0xe0, 0x89, 0x79, 0x4f, 0x62, 0x2f, 0xf1, 0x81, 0x57, 0x4d, 0x0f, - 0xbc, 0xdc, 0xfe, 0x6a, 0xf9, 0xfd, 0x99, 0x7f, 0xa8, 0xc2, 0x6c, 0xc6, 0x81, 0xca, 0x0e, 0x4c, - 0x51, 0x0c, 0x4a, 0xbf, 0x95, 0x6d, 0xa1, 0x3c, 0x14, 0x5a, 0x56, 0x06, 0x82, 0xf6, 0x01, 0x18, - 0x0e, 0xb0, 0x4b, 0x38, 0x09, 0x44, 0x26, 0x17, 0x11, 0xff, 0x60, 0xf2, 0xec, 0xb2, 0x1b, 0xd3, - 0xb4, 0x32, 0xe4, 0x45, 0x35, 0x2b, 0x59, 0x87, 0x3a, 0x7f, 0xeb, 0x11, 0xfa, 0x02, 0xe6, 0xf7, - 0xa8, 0x43, 0x76, 0x53, 0x41, 0xa6, 0xa5, 0x20, 0x8f, 0x27, 0x17, 0xe4, 0x5e, 0x96, 0xae, 0x55, - 0x60, 0x63, 0x5e, 0x83, 0xc5, 0x62, 0x3c, 0x09, 0x21, 0xa9, 0x8b, 0xfb, 0x89, 0xb6, 0xf4, 0xc8, - 0x44, 0xb0, 0x58, 0x8c, 0x1f, 0xf3, 0x9f, 0x55, 0x38, 0x9b, 0x90, 0xdb, 0xf0, 0x3c, 0x3f, 0xf2, - 0x6c, 0x79, 0x75, 0x58, 0x6a, 0x8b, 0x33, 0xd0, 0xe0, 0x94, 0x3b, 0x49, 0xe1, 0x23, 0x07, 0xe2, - 0xec, 0xe2, 0xbe, 0xef, 0x70, 0xca, 0xb4, 0x81, 0xe3, 0xa1, 0xb2, 0xfd, 0x8b, 0x88, 0x06, 0xa4, - 0x27, 0x33, 0x41, 0xd3, 0x4a, 0xc6, 0x62, 0x4e, 0x54, 0x35, 0xb2, 0xc4, 0x57, 0xca, 0x4c, 0xc6, - 0xd2, 0xef, 0x7d, 0xc7, 0x21, 0xb6, 0x50, 0x47, 0xa6, 0x09, 0x28, 0x40, 0x65, 0x73, 0xc1, 0x03, - 0xea, 0xf5, 0x75, 0x0b, 0xa0, 0x47, 0x42, 0x4e, 0x1c, 0x04, 0xf8, 0x50, 0x57, 0xfe, 0x6a, 0x80, - 0x3e, 0x84, 0x9a, 0x8b, 0x99, 0x3e, 0xe8, 0xae, 0xe5, 0xb2, 0x43, 0x99, 0x06, 0x3a, 0x3b, 0x98, - 0xa9, 0x93, 0x40, 0x2c, 0x6b, 0xbf, 0x0f, 0xcd, 0x18, 0xf0, 0xa5, 0x4a, 0xc2, 0xcf, 0x61, 0x2e, - 0x97, 0x7c, 0xd0, 0x33, 0x58, 0x4e, 0x3d, 0x2a, 0xcb, 0x50, 0x17, 0x81, 0x6f, 0x1d, 0x29, 0x99, - 0x35, 0x82, 0x80, 0xf9, 0x02, 0x96, 0x84, 0xcb, 0xc8, 0xc0, 0x3f, 0xa1, 0xd6, 0xe6, 0x03, 0x68, - 0x25, 0x2c, 0x4b, 0x7d, 0xa6, 0x0d, 0xcd, 0x83, 0xf8, 0x4a, 0x57, 0xf5, 0x36, 0xc9, 0xd8, 0xdc, - 0x00, 0x94, 0x95, 0x57, 0x9f, 0x40, 0xd7, 0xf3, 0x45, 0xf1, 0xd9, 0xe2, 0x71, 0x23, 0xd1, 0xe3, - 0x9a, 0xf8, 0xef, 0x55, 0x58, 0xd8, 0xa2, 0xf2, 0x8e, 0xe4, 0x84, 0x92, 0xdc, 0x35, 0x58, 0x0c, - 0xa3, 0xae, 0xeb, 0xf7, 0x22, 0x87, 0xe8, 0xa2, 0x40, 0x9f, 0xf4, 0x43, 0xf0, 0x71, 0xc9, 0x4f, - 0x28, 0x8b, 0x61, 0x3e, 0xd0, 0xdd, 0xaf, 0xfc, 0x46, 0x1f, 0xc2, 0xf9, 0x47, 0xe4, 0x0b, 0xbd, - 0x9f, 0x2d, 0xc7, 0xef, 0x76, 0xa9, 0xd7, 0x8f, 0x99, 0x34, 0x24, 0x93, 0xd1, 0x08, 0x65, 0xa5, - 0xe2, 0x74, 0x79, 0xa9, 0x98, 0x74, 0xd0, 0x9b, 0xbe, 0xeb, 0x52, 0xae, 0x2b, 0xca, 0x1c, 0xcc, - 0xfc, 0x79, 0x05, 0x16, 0x53, 0xcd, 0x6a, 0xdb, 0xdc, 0x52, 0x31, 0xa4, 0x2c, 0x73, 0x39, 0x6b, - 0x99, 0x22, 0xea, 0x7f, 0x1e, 0x3e, 0xa7, 0xb2, 0xe1, 0xf3, 0xab, 0x2a, 0x9c, 0xdd, 0xa2, 0x3c, - 0x4e, 0x5c, 0xf4, 0x7f, 0xcd, 0xca, 0x25, 0x36, 0xa9, 0x1f, 0xcf, 0x26, 0x8d, 0x12, 0x9b, 0x74, - 0x60, 0xb9, 0xa8, 0x0c, 0x6d, 0x98, 0x33, 0xd0, 0x60, 0xf2, 0xd2, 0x59, 0xdd, 0x2b, 0xa8, 0x81, - 0xf9, 0xb3, 0x19, 0xb8, 0xf4, 0x29, 0xeb, 0x61, 0x9e, 0xdc, 0x19, 0xdd, 0xf3, 0x03, 0x79, 0xeb, - 0x7c, 0x32, 0x5a, 0x2c, 0xbc, 0x0c, 0x56, 0xc7, 0xbe, 0x0c, 0xd6, 0xc6, 0xbc, 0x0c, 0xd6, 0x8f, - 0xf5, 0x32, 0xd8, 0x38, 0xb1, 0x97, 0xc1, 0xe1, 0x5e, 0x6b, 0xba, 0xb4, 0xd7, 0x7a, 0x96, 0xeb, - 0x47, 0x66, 0x64, 0xd8, 0x7c, 0x2b, 0x1b, 0x36, 0x63, 0xad, 0x33, 0xf6, 0x49, 0xa3, 0xf0, 0xa0, - 0xd6, 0x3c, 0xf2, 0x41, 0xad, 0x35, 0xfc, 0xa0, 0x56, 0xfe, 0x26, 0x03, 0x23, 0xdf, 0x64, 0xae, - 0xc0, 0x7c, 0x78, 0xe8, 0xd9, 0xa4, 0x97, 0xdc, 0x24, 0xce, 0xaa, 0x6d, 0xe7, 0xa1, 0xb9, 0x88, - 0x38, 0x55, 0x88, 0x88, 0xc4, 0x53, 0xe7, 0x32, 0x9e, 0x5a, 0x16, 0x27, 0xf3, 0x23, 0xdb, 0xdc, - 0xc2, 0x73, 0xc9, 0x42, 0xe9, 0x73, 0xc9, 0x7f, 0x4d, 0xb3, 0xf5, 0x19, 0xac, 0x8c, 0xb2, 0xb2, - 0x0e, 0x5e, 0x03, 0x66, 0xec, 0x01, 0xf6, 0xfa, 0xf2, 0x5a, 0x50, 0x76, 0xff, 0x7a, 0x38, 0xae, - 0x3b, 0x58, 0xff, 0x23, 0xc0, 0x52, 0x5a, 0xf5, 0x8b, 0xbf, 0xd4, 0x26, 0xe8, 0x31, 0x2c, 0xc6, - 0xcf, 0x4b, 0xf1, 0x45, 0x2e, 0x1a, 0xf7, 0x76, 0xd2, 0xbe, 0x58, 0x3e, 0xa9, 0x44, 0x33, 0xa7, - 0x90, 0x0d, 0xe7, 0x8b, 0x04, 0xd3, 0x67, 0x9a, 0x6f, 0x8c, 0xa1, 0x9c, 0x60, 0x1d, 0xc5, 0xe2, - 0x6a, 0x05, 0x3d, 0x83, 0xf9, 0xfc, 0x63, 0x02, 0xca, 0x95, 0x41, 0xa5, 0xef, 0x1b, 0x6d, 0x73, - 0x1c, 0x4a, 0x22, 0xff, 0x73, 0xe1, 0x06, 0xb9, 0x7b, 0x73, 0x64, 0xe6, 0x6f, 0x04, 0xca, 0x5e, - 0x1e, 0xda, 0x5f, 0x1f, 0x8b, 0x93, 0x50, 0xff, 0x00, 0x9a, 0xf1, 0x5d, 0x72, 0x5e, 0xcd, 0x85, - 0x1b, 0xe6, 0xf6, 0x62, 0x9e, 0xde, 0x5e, 0x68, 0x4e, 0xa1, 0x8f, 0xd4, 0xe2, 0x0d, 0xc6, 0x4a, - 0x16, 0x67, 0x6e, 0x50, 0xdb, 0xa7, 0x4b, 0x6e, 0x2d, 0xcd, 0x29, 0xf4, 0x1d, 0x98, 0x15, 0x5f, - 0xbb, 0xfa, 0x79, 0x7f, 0xb9, 0xa3, 0x7e, 0x4d, 0xd2, 0x89, 0x7f, 0x4d, 0xd2, 0xb9, 0xeb, 0x32, - 0x7e, 0xd8, 0x2e, 0xb9, 0x56, 0xd4, 0x04, 0x9e, 0xc3, 0xdc, 0x16, 0xe1, 0xe9, 0x2d, 0x00, 0xba, - 0x7c, 0xac, 0xbb, 0x92, 0xb6, 0x59, 0x44, 0x1b, 0xbe, 0x48, 0x30, 0xa7, 0xd0, 0xaf, 0x2b, 0x70, - 0x7a, 0x8b, 0xf0, 0x62, 0x5f, 0x8d, 0xde, 0x2d, 0x67, 0x32, 0xa2, 0xff, 0x6e, 0x3f, 0x9a, 0x34, - 0x26, 0xf3, 0x64, 0xcd, 0x29, 0xf4, 0x9b, 0x0a, 0x9c, 0xcb, 0x08, 0x96, 0x6d, 0x94, 0xd1, 0x8d, - 0xf1, 0xc2, 0x95, 0x34, 0xd5, 0xed, 0x4f, 0x26, 0xfc, 0xd5, 0x46, 0x86, 0xa4, 0x39, 0x85, 0x76, - 0xa5, 0x4d, 0xd2, 0xba, 0x18, 0x5d, 0x2a, 0x2d, 0x80, 0x13, 0xee, 0x2b, 0xa3, 0xa6, 0x13, 0x3b, - 0x7c, 0x02, 0xb3, 0x5b, 0x84, 0xc7, 0x05, 0x5a, 0xde, 0xd3, 0x0a, 0xb5, 0x73, 0x3e, 0x54, 0x8b, - 0x35, 0x9d, 0xf4, 0x98, 0x25, 0x45, 0x2b, 0x53, 0x84, 0xe4, 0x63, 0xb5, 0xb4, 0x5a, 0xcb, 0x7b, - 0x4c, 0x79, 0x0d, 0x63, 0x4e, 0xa1, 0x17, 0xb0, 0x5c, 0x9e, 0x2a, 0xd1, 0xdb, 0xc7, 0x3e, 0x34, - 0xdb, 0xd7, 0x8e, 0x83, 0x1a, 0xb3, 0xfc, 0x78, 0xe3, 0x2f, 0xaf, 0x56, 0x2a, 0x7f, 0x7d, 0xb5, - 0x52, 0xf9, 0xd7, 0xab, 0x95, 0xca, 0xf7, 0x6f, 0x1e, 0xf1, 0xeb, 0xae, 0xcc, 0x0f, 0xc6, 0x30, - 0xa3, 0xb6, 0x43, 0x89, 0xc7, 0xbb, 0xd3, 0x32, 0xde, 0x6e, 0xfe, 0x3b, 0x00, 0x00, 0xff, 0xff, - 0xa5, 0xe0, 0xaa, 0x70, 0x4f, 0x26, 0x00, 0x00, +func (m *ChangeRevisionRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) } - -// Reference imports to suppress errors if they are not otherwise used. -var _ context.Context -var _ grpc.ClientConn +func (m *ChangeRevisionRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ChangeRevisionRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *ChangeRevisionRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_ChangeRevisionRequest.Merge(m, src) +} +func (m *ChangeRevisionRequest) XXX_Size() int { + return m.Size() +} +func (m *ChangeRevisionRequest) XXX_DiscardUnknown() { + xxx_messageInfo_ChangeRevisionRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_ChangeRevisionRequest proto.InternalMessageInfo + +func (m *ChangeRevisionRequest) GetAppName() string { + if m != nil { + return m.AppName + } + return "" +} + +func (m *ChangeRevisionRequest) GetNamespace() string { + if m != nil { + return m.Namespace + } + return "" +} + +func (m *ChangeRevisionRequest) GetCurrentRevision() string { + if m != nil { + return m.CurrentRevision + } + return "" +} + +func (m *ChangeRevisionRequest) GetPreviousRevision() string { + if m != nil { + return m.PreviousRevision + } + return "" +} + +func (m *ChangeRevisionRequest) GetPaths() []string { + if m != nil { + return m.Paths + } + return nil +} + +func (m *ChangeRevisionRequest) GetRepo() *v1alpha1.Repository { + if m != nil { + return m.Repo + } + return nil +} + +type ChangeRevisionResponse struct { + Revision string `protobuf:"bytes,1,opt,name=revision,proto3" json:"revision,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ChangeRevisionResponse) Reset() { *m = ChangeRevisionResponse{} } +func (m *ChangeRevisionResponse) String() string { return proto.CompactTextString(m) } +func (*ChangeRevisionResponse) ProtoMessage() {} +func (*ChangeRevisionResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_dd8723cfcc820480, []int{37} +} +func (m *ChangeRevisionResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ChangeRevisionResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ChangeRevisionResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *ChangeRevisionResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_ChangeRevisionResponse.Merge(m, src) +} +func (m *ChangeRevisionResponse) XXX_Size() int { + return m.Size() +} +func (m *ChangeRevisionResponse) XXX_DiscardUnknown() { + xxx_messageInfo_ChangeRevisionResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_ChangeRevisionResponse proto.InternalMessageInfo + +func (m *ChangeRevisionResponse) GetRevision() string { + if m != nil { + return m.Revision + } + return "" +} + +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") + proto.RegisterType((*TestRepositoryRequest)(nil), "repository.TestRepositoryRequest") + proto.RegisterType((*TestRepositoryResponse)(nil), "repository.TestRepositoryResponse") + proto.RegisterType((*ResolveRevisionRequest)(nil), "repository.ResolveRevisionRequest") + proto.RegisterType((*ResolveRevisionResponse)(nil), "repository.ResolveRevisionResponse") + proto.RegisterType((*Manifest)(nil), "repository.Manifest") + proto.RegisterType((*Dependencies)(nil), "repository.Dependencies") + proto.RegisterType((*ApplicationVersions)(nil), "repository.ApplicationVersions") + proto.RegisterType((*ManifestResponse)(nil), "repository.ManifestResponse") + proto.RegisterType((*ListRefsRequest)(nil), "repository.ListRefsRequest") + proto.RegisterType((*Refs)(nil), "repository.Refs") + proto.RegisterType((*ListAppsRequest)(nil), "repository.ListAppsRequest") + proto.RegisterMapType((map[string]bool)(nil), "repository.ListAppsRequest.EnabledSourceTypesEntry") + proto.RegisterType((*AppList)(nil), "repository.AppList") + proto.RegisterMapType((map[string]string)(nil), "repository.AppList.AppsEntry") + proto.RegisterType((*PluginInfo)(nil), "repository.PluginInfo") + 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((*RepoServerRevisionChartDetailsRequest)(nil), "repository.RepoServerRevisionChartDetailsRequest") + proto.RegisterType((*HelmAppSpec)(nil), "repository.HelmAppSpec") + proto.RegisterType((*KustomizeAppSpec)(nil), "repository.KustomizeAppSpec") + proto.RegisterType((*DirectoryAppSpec)(nil), "repository.DirectoryAppSpec") + proto.RegisterType((*ParameterAnnouncement)(nil), "repository.ParameterAnnouncement") + proto.RegisterMapType((map[string]string)(nil), "repository.ParameterAnnouncement.MapEntry") + proto.RegisterType((*PluginAppSpec)(nil), "repository.PluginAppSpec") + proto.RegisterType((*HelmChartsRequest)(nil), "repository.HelmChartsRequest") + proto.RegisterType((*HelmChart)(nil), "repository.HelmChart") + proto.RegisterType((*HelmChartsResponse)(nil), "repository.HelmChartsResponse") + proto.RegisterType((*GitFilesRequest)(nil), "repository.GitFilesRequest") + proto.RegisterType((*GitFilesResponse)(nil), "repository.GitFilesResponse") + proto.RegisterMapType((map[string][]byte)(nil), "repository.GitFilesResponse.MapEntry") + proto.RegisterType((*GitDirectoriesRequest)(nil), "repository.GitDirectoriesRequest") + proto.RegisterType((*GitDirectoriesResponse)(nil), "repository.GitDirectoriesResponse") + proto.RegisterType((*UpdateRevisionForPathsRequest)(nil), "repository.UpdateRevisionForPathsRequest") + proto.RegisterMapType((map[string]*v1alpha1.RefTarget)(nil), "repository.UpdateRevisionForPathsRequest.RefSourcesEntry") + proto.RegisterType((*UpdateRevisionForPathsResponse)(nil), "repository.UpdateRevisionForPathsResponse") + proto.RegisterType((*ChangeRevisionRequest)(nil), "repository.ChangeRevisionRequest") + proto.RegisterType((*ChangeRevisionResponse)(nil), "repository.ChangeRevisionResponse") +} + +func init() { + proto.RegisterFile("reposerver/repository/repository.proto", fileDescriptor_dd8723cfcc820480) +} + +var fileDescriptor_dd8723cfcc820480 = []byte{ + // 2750 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x3a, 0x5b, 0x73, 0x1c, 0x47, + 0xd5, 0xda, 0x9b, 0xb4, 0x7b, 0x56, 0xd6, 0xa5, 0x6d, 0xcb, 0xe3, 0xb5, 0xad, 0x28, 0xf3, 0x25, + 0x2e, 0xc7, 0x49, 0x76, 0x3f, 0x29, 0x57, 0x92, 0x10, 0x50, 0x64, 0x5b, 0x52, 0x1c, 0xd9, 0xca, + 0xd8, 0x09, 0x95, 0x10, 0xa0, 0x7a, 0x67, 0x5b, 0xbb, 0x93, 0x9d, 0x4b, 0x67, 0xa6, 0x57, 0x89, + 0x52, 0x45, 0x15, 0x05, 0x14, 0x2f, 0xbc, 0x53, 0x05, 0x6f, 0x54, 0x7e, 0x03, 0xc5, 0x23, 0xbc, + 0x50, 0xf0, 0x48, 0xf1, 0xc2, 0x23, 0x94, 0x7f, 0x09, 0xd5, 0x97, 0x99, 0xe9, 0x99, 0x9d, 0x5d, + 0x29, 0xc8, 0x56, 0x80, 0x17, 0xa9, 0xfb, 0xcc, 0xe9, 0xd3, 0xa7, 0x4f, 0x9f, 0x7b, 0x2f, 0x5c, + 0x0f, 0x09, 0x0d, 0x22, 0x12, 0x1e, 0x92, 0xb0, 0x23, 0x86, 0x0e, 0x0b, 0xc2, 0x23, 0x6d, 0xd8, + 0xa6, 0x61, 0xc0, 0x02, 0x04, 0x29, 0xa4, 0x65, 0x0e, 0x5f, 0x8f, 0xda, 0x4e, 0xd0, 0xc1, 0xd4, + 0xe9, 0xd8, 0x41, 0x48, 0x3a, 0x87, 0xeb, 0x9d, 0x3e, 0xf1, 0x49, 0x88, 0x19, 0xe9, 0x49, 0xfc, + 0xd6, 0xcb, 0x29, 0x8e, 0x87, 0xed, 0x81, 0xe3, 0x93, 0xf0, 0xa8, 0x43, 0x87, 0x7d, 0x0e, 0x88, + 0x3a, 0x1e, 0x61, 0xb8, 0x68, 0xd5, 0x7b, 0x7d, 0x87, 0x0d, 0x46, 0xdd, 0xb6, 0x1d, 0x78, 0x1d, + 0x1c, 0xf6, 0x03, 0x1a, 0x06, 0x9f, 0x8a, 0xc1, 0x8b, 0x76, 0xaf, 0x73, 0xb8, 0x91, 0x12, 0xc0, + 0x94, 0xba, 0x8e, 0x8d, 0x99, 0x13, 0xf8, 0x9d, 0xc3, 0x75, 0xec, 0xd2, 0x01, 0x1e, 0xa7, 0x76, + 0xa5, 0x1f, 0x04, 0x7d, 0x97, 0x74, 0xc4, 0xac, 0x3b, 0x3a, 0xe8, 0x10, 0x8f, 0x32, 0x75, 0x20, + 0xf3, 0x8f, 0x0b, 0xb0, 0xb8, 0x87, 0x7d, 0xe7, 0x80, 0x44, 0xcc, 0x22, 0x9f, 0x8d, 0x48, 0xc4, + 0xd0, 0x27, 0x50, 0xe5, 0xc7, 0x34, 0x4a, 0x6b, 0xa5, 0x1b, 0xcd, 0x8d, 0x9d, 0x76, 0xca, 0x4d, + 0x3b, 0xe6, 0x46, 0x0c, 0x7e, 0x64, 0xf7, 0xda, 0x87, 0x1b, 0x6d, 0x3a, 0xec, 0xb7, 0x39, 0x37, + 0x6d, 0x8d, 0x9b, 0x76, 0xcc, 0x4d, 0xdb, 0x4a, 0x04, 0x66, 0x09, 0xaa, 0xa8, 0x05, 0xf5, 0x90, + 0x1c, 0x3a, 0x91, 0x13, 0xf8, 0x46, 0x79, 0xad, 0x74, 0xa3, 0x61, 0x25, 0x73, 0x64, 0xc0, 0x9c, + 0x1f, 0x6c, 0x61, 0x7b, 0x40, 0x8c, 0xca, 0x5a, 0xe9, 0x46, 0xdd, 0x8a, 0xa7, 0x68, 0x0d, 0x9a, + 0x98, 0xd2, 0xf7, 0x70, 0x97, 0xb8, 0x77, 0xc9, 0x91, 0x51, 0x15, 0x0b, 0x75, 0x10, 0x5f, 0x8b, + 0x29, 0xbd, 0x87, 0x3d, 0x62, 0xd4, 0xc4, 0xd7, 0x78, 0x8a, 0xae, 0x42, 0xc3, 0xc7, 0x1e, 0x89, + 0x28, 0xb6, 0x89, 0x51, 0x17, 0xdf, 0x52, 0x00, 0xfa, 0x31, 0x2c, 0x6b, 0x8c, 0x3f, 0x08, 0x46, + 0xa1, 0x4d, 0x0c, 0x10, 0x47, 0xbf, 0x7f, 0xba, 0xa3, 0x6f, 0xe6, 0xc9, 0x5a, 0xe3, 0x3b, 0xa1, + 0x1f, 0x42, 0x4d, 0xe8, 0x94, 0xd1, 0x5c, 0xab, 0x3c, 0x56, 0x69, 0x4b, 0xb2, 0xc8, 0x87, 0x39, + 0xea, 0x8e, 0xfa, 0x8e, 0x1f, 0x19, 0xf3, 0x62, 0x87, 0x87, 0xa7, 0xdb, 0x61, 0x2b, 0xf0, 0x0f, + 0x9c, 0xfe, 0x1e, 0xf6, 0x71, 0x9f, 0x78, 0xc4, 0x67, 0xfb, 0x82, 0xb8, 0x15, 0x6f, 0x82, 0xbe, + 0x84, 0xa5, 0xe1, 0x28, 0x62, 0x81, 0xe7, 0x7c, 0x49, 0xee, 0x53, 0xbe, 0x36, 0x32, 0xce, 0x09, + 0x69, 0xde, 0x3b, 0xdd, 0xc6, 0x77, 0x73, 0x54, 0xad, 0xb1, 0x7d, 0xb8, 0x92, 0x0c, 0x47, 0x5d, + 0xf2, 0x21, 0x09, 0x85, 0x76, 0x2d, 0x48, 0x25, 0xd1, 0x40, 0x52, 0x8d, 0x1c, 0x35, 0x8b, 0x8c, + 0xc5, 0xb5, 0x8a, 0x54, 0xa3, 0x04, 0x84, 0x6e, 0xc0, 0xe2, 0x21, 0x09, 0x9d, 0x83, 0xa3, 0x07, + 0x4e, 0xdf, 0xc7, 0x6c, 0x14, 0x12, 0x63, 0x49, 0xa8, 0x62, 0x1e, 0x8c, 0x3c, 0x38, 0x37, 0x20, + 0xae, 0xc7, 0x45, 0xbe, 0x15, 0x92, 0x5e, 0x64, 0x2c, 0x0b, 0xf9, 0x6e, 0x9f, 0xfe, 0x06, 0x05, + 0x39, 0x2b, 0x4b, 0x9d, 0x33, 0xe6, 0x07, 0x96, 0xb2, 0x14, 0x69, 0x23, 0x48, 0x32, 0x96, 0x03, + 0xa3, 0xeb, 0xb0, 0xc0, 0x42, 0x6c, 0x0f, 0x1d, 0xbf, 0xbf, 0x47, 0xd8, 0x20, 0xe8, 0x19, 0xe7, + 0x85, 0x24, 0x72, 0x50, 0x64, 0x03, 0x22, 0x3e, 0xee, 0xba, 0xa4, 0x27, 0x75, 0xf1, 0xe1, 0x11, + 0x25, 0x91, 0x71, 0x41, 0x9c, 0xe2, 0xa5, 0xb6, 0xe6, 0xfb, 0x72, 0x0e, 0xa2, 0x7d, 0x7b, 0x6c, + 0xd5, 0x6d, 0x9f, 0x85, 0x47, 0x56, 0x01, 0x39, 0x34, 0x84, 0x26, 0x3f, 0x47, 0xac, 0x0a, 0x17, + 0x85, 0x2a, 0xec, 0x9e, 0x4e, 0x46, 0x3b, 0x29, 0x41, 0x4b, 0xa7, 0x8e, 0xda, 0x80, 0x06, 0x38, + 0xda, 0x1b, 0xb9, 0xcc, 0xa1, 0x2e, 0x91, 0x6c, 0x44, 0xc6, 0x8a, 0x10, 0x53, 0xc1, 0x17, 0x74, + 0x17, 0x20, 0x24, 0x07, 0x31, 0xde, 0x25, 0x71, 0xf2, 0xe7, 0xa7, 0x9d, 0xdc, 0x4a, 0xb0, 0xe5, + 0x89, 0xb5, 0xe5, 0x7c, 0x73, 0x7e, 0x0c, 0x62, 0x33, 0x65, 0xed, 0xc2, 0xac, 0x0d, 0xa1, 0x62, + 0x05, 0x5f, 0xb8, 0x2e, 0x2a, 0xa8, 0x70, 0x5a, 0x97, 0xa5, 0xb6, 0x6a, 0x20, 0xb4, 0x03, 0x4f, + 0x61, 0xdf, 0x0f, 0x98, 0x38, 0x7e, 0xcc, 0xca, 0xb6, 0x72, 0xef, 0xfb, 0x98, 0x0d, 0x22, 0xa3, + 0x25, 0x56, 0x1d, 0x87, 0xc6, 0x55, 0xc2, 0xf1, 0x23, 0x86, 0x5d, 0x57, 0x20, 0xed, 0xde, 0x32, + 0xae, 0x48, 0x95, 0xc8, 0x42, 0x51, 0x17, 0xce, 0x6b, 0x12, 0xdf, 0x23, 0x0c, 0xf7, 0x30, 0xc3, + 0xc6, 0x55, 0x71, 0x6b, 0xff, 0xdf, 0x96, 0xd1, 0xac, 0xad, 0x47, 0xb3, 0xf4, 0xaa, 0x78, 0x34, + 0x6b, 0x1f, 0xae, 0xb7, 0xef, 0x77, 0xf9, 0x01, 0xf8, 0x5a, 0xab, 0x88, 0x58, 0xeb, 0x36, 0x5c, + 0x9a, 0xa0, 0x40, 0x68, 0x09, 0x2a, 0x43, 0x72, 0x24, 0x02, 0x4f, 0xc3, 0xe2, 0x43, 0x74, 0x01, + 0x6a, 0x87, 0xd8, 0x1d, 0x11, 0x11, 0x2a, 0xea, 0x96, 0x9c, 0xbc, 0x51, 0x7e, 0xbd, 0xd4, 0xfa, + 0x45, 0x09, 0x16, 0x73, 0xd7, 0x51, 0xb0, 0xfe, 0x07, 0xfa, 0xfa, 0xc7, 0x60, 0x9c, 0x07, 0x0f, + 0x71, 0xd8, 0x27, 0x4c, 0x63, 0xc4, 0xfc, 0x5b, 0x09, 0x8c, 0x9c, 0x9e, 0x7c, 0xcf, 0x61, 0x83, + 0x3b, 0x8e, 0x4b, 0x22, 0xf4, 0x1a, 0xcc, 0x85, 0x12, 0xa6, 0xc2, 0xe9, 0x95, 0x29, 0xea, 0xb5, + 0x33, 0x63, 0xc5, 0xd8, 0xe8, 0x6d, 0xa8, 0x7b, 0xb1, 0xf8, 0x25, 0xef, 0x6b, 0x45, 0x2b, 0xf9, + 0x2e, 0xb1, 0x64, 0x77, 0x66, 0xac, 0x64, 0x0d, 0x7a, 0x05, 0x6a, 0xf6, 0x60, 0xe4, 0x0f, 0x45, + 0x20, 0x6d, 0x6e, 0x5c, 0x9b, 0xb4, 0x78, 0x8b, 0x23, 0xed, 0xcc, 0x58, 0x12, 0xfb, 0x9d, 0x59, + 0xa8, 0x52, 0x1c, 0x32, 0xf3, 0x0e, 0x5c, 0x28, 0xda, 0x82, 0x47, 0x6f, 0x7b, 0x40, 0xec, 0x61, + 0x34, 0xf2, 0x94, 0x98, 0x93, 0x39, 0x42, 0x50, 0x8d, 0x9c, 0x2f, 0xa5, 0xa8, 0x2b, 0x96, 0x18, + 0x9b, 0xcf, 0xc1, 0xf2, 0xd8, 0x6e, 0xfc, 0x52, 0x25, 0x6f, 0x9c, 0xc2, 0xbc, 0xda, 0xda, 0x1c, + 0xc1, 0xc5, 0x87, 0x42, 0x16, 0x49, 0x08, 0x3b, 0x8b, 0x7c, 0xc4, 0xdc, 0x81, 0x95, 0xfc, 0xb6, + 0x11, 0x0d, 0xfc, 0x88, 0x70, 0x83, 0x16, 0x3e, 0xdf, 0x21, 0xbd, 0xf4, 0xab, 0xe0, 0xa2, 0x6e, + 0x15, 0x7c, 0x31, 0xbf, 0x2a, 0xc3, 0x8a, 0x45, 0xa2, 0xc0, 0x3d, 0x24, 0xb1, 0x43, 0x3e, 0x9b, + 0x94, 0xea, 0xfb, 0x50, 0xc1, 0x94, 0x2a, 0x35, 0xd9, 0x7d, 0x6c, 0x49, 0x8b, 0xc5, 0xa9, 0xa2, + 0x17, 0x60, 0x19, 0x7b, 0x5d, 0xa7, 0x3f, 0x0a, 0x46, 0x51, 0x7c, 0x2c, 0xa1, 0x54, 0x0d, 0x6b, + 0xfc, 0x03, 0x77, 0x6a, 0x91, 0xb0, 0xc8, 0x5d, 0xbf, 0x47, 0xbe, 0x10, 0x79, 0x5a, 0xc5, 0xd2, + 0x41, 0xa6, 0x0d, 0x97, 0xc6, 0x84, 0xa4, 0x04, 0xae, 0xa7, 0x86, 0xa5, 0x5c, 0x6a, 0x58, 0xc8, + 0x46, 0x79, 0x02, 0x1b, 0xe6, 0x4f, 0x4a, 0x50, 0x8f, 0xf5, 0x0e, 0xdd, 0x84, 0x25, 0x3b, 0xf0, + 0xa8, 0xe3, 0x92, 0x5e, 0x0c, 0x53, 0xe4, 0xc7, 0xe0, 0x9c, 0xff, 0x10, 0x7f, 0x9e, 0xa0, 0xc9, + 0x0d, 0x74, 0x10, 0xd7, 0x72, 0x8a, 0xd9, 0x40, 0x89, 0x40, 0x8c, 0x39, 0xcc, 0x75, 0x7c, 0x22, + 0x8e, 0x5b, 0xb3, 0xc4, 0xd8, 0xfc, 0x18, 0xe6, 0x6f, 0x11, 0x4a, 0xfc, 0x1e, 0xf1, 0x6d, 0x87, + 0x44, 0x02, 0x27, 0xb0, 0x87, 0x6a, 0x67, 0x31, 0xe6, 0xb0, 0x1e, 0xa1, 0x91, 0xda, 0x46, 0x8c, + 0x91, 0x09, 0xf3, 0xdc, 0x07, 0x38, 0xa1, 0x48, 0xaf, 0x22, 0xb5, 0x4f, 0x06, 0x66, 0x46, 0x70, + 0x5e, 0xbb, 0xa7, 0x24, 0x77, 0x59, 0x05, 0xc0, 0x94, 0xc6, 0xe9, 0x8f, 0xdc, 0x48, 0x83, 0xa0, + 0xb7, 0x60, 0xbe, 0xa7, 0xb1, 0xa4, 0x14, 0xc6, 0xd0, 0x5d, 0x83, 0xce, 0xb2, 0x95, 0xc1, 0x36, + 0xbf, 0xaa, 0xc2, 0x52, 0xea, 0xb0, 0xd4, 0x95, 0x6d, 0x40, 0xc3, 0x53, 0xb0, 0xc8, 0x28, 0x89, + 0x00, 0x7a, 0xa1, 0xd0, 0xc3, 0xa5, 0x68, 0xd9, 0x7c, 0xbc, 0x9c, 0xcf, 0xc7, 0x57, 0x60, 0x56, + 0x16, 0x62, 0xea, 0xe4, 0x6a, 0x96, 0x51, 0x8e, 0x6a, 0x4e, 0x39, 0x56, 0x01, 0xa2, 0x24, 0x96, + 0x18, 0xb3, 0xf2, 0xe0, 0x29, 0x84, 0xcb, 0x54, 0x66, 0x6f, 0x16, 0x89, 0x46, 0x2e, 0x33, 0xe6, + 0xa4, 0x4c, 0x75, 0x18, 0x7a, 0x06, 0xce, 0xd9, 0x81, 0xe7, 0x39, 0x6c, 0x8f, 0x44, 0x11, 0xee, + 0xc7, 0x95, 0x42, 0x16, 0xc8, 0x29, 0x49, 0xc0, 0xe6, 0x88, 0x0d, 0x82, 0xd0, 0x68, 0x48, 0x4a, + 0x3a, 0x0c, 0xbd, 0x0b, 0x20, 0xe7, 0xb7, 0x30, 0x8b, 0x4b, 0x89, 0x9b, 0x27, 0x8b, 0x9d, 0x0f, + 0x1d, 0x8f, 0x58, 0xda, 0x6a, 0xf4, 0x7e, 0x26, 0x20, 0x27, 0x89, 0x6b, 0x53, 0x10, 0x7d, 0x4a, + 0x97, 0x74, 0x81, 0x42, 0x58, 0x45, 0x6b, 0xd1, 0x77, 0xe1, 0x8a, 0x14, 0x4d, 0x14, 0x5f, 0x4e, + 0xf4, 0x80, 0xe1, 0x90, 0x39, 0x7e, 0x7f, 0xb7, 0xf7, 0x85, 0xa8, 0x12, 0x6a, 0xd6, 0x34, 0x14, + 0x11, 0x04, 0x02, 0xcf, 0xc3, 0x7e, 0x8f, 0xe7, 0xf6, 0x15, 0x11, 0x04, 0xd4, 0xdc, 0x0c, 0x60, + 0xf1, 0x3d, 0x87, 0x2b, 0xc8, 0x41, 0x74, 0x36, 0xfe, 0xfb, 0x55, 0xa8, 0xf2, 0xcd, 0x38, 0x53, + 0xdd, 0x10, 0xfb, 0xf6, 0x80, 0x48, 0x45, 0x6c, 0x58, 0xc9, 0x9c, 0xdb, 0x19, 0xc3, 0x7d, 0xae, + 0xf0, 0x1c, 0x2e, 0xc6, 0xe6, 0xef, 0xcb, 0x92, 0xd3, 0x4d, 0x4a, 0xa3, 0x6f, 0xbe, 0xf2, 0x2d, + 0xce, 0xc5, 0x2b, 0xe3, 0xb9, 0x78, 0x8e, 0xe5, 0xaf, 0x93, 0x8b, 0x3f, 0xa6, 0xcc, 0xcb, 0x1c, + 0xc1, 0xdc, 0x26, 0xa5, 0x9c, 0x11, 0xb4, 0x0e, 0x55, 0x4c, 0x69, 0x6c, 0xf9, 0xd7, 0x72, 0xfa, + 0xc8, 0x51, 0xf8, 0x7f, 0xc5, 0x92, 0x40, 0x6d, 0xbd, 0x06, 0x8d, 0x04, 0x74, 0xdc, 0xb6, 0x0d, + 0x7d, 0xdb, 0x35, 0x00, 0x59, 0x6c, 0xee, 0xfa, 0x07, 0x01, 0xbf, 0x52, 0xee, 0x33, 0x62, 0x77, + 0xca, 0xc7, 0xe6, 0x1b, 0x31, 0x86, 0xe0, 0xed, 0x05, 0xa8, 0x39, 0x8c, 0x78, 0x31, 0x73, 0x2b, + 0x3a, 0x73, 0x29, 0x21, 0x4b, 0x22, 0x99, 0x7f, 0xae, 0xc3, 0x65, 0x7e, 0x63, 0x0f, 0x84, 0xb7, + 0xd9, 0xa4, 0xf4, 0x16, 0x61, 0xd8, 0x71, 0xa3, 0xf7, 0x47, 0x24, 0x3c, 0x7a, 0xc2, 0x8a, 0xd1, + 0x87, 0x59, 0x69, 0x6e, 0xca, 0x23, 0x3f, 0xf6, 0xbe, 0x83, 0x22, 0x9f, 0x36, 0x1b, 0x2a, 0x4f, + 0xa6, 0xd9, 0x50, 0x54, 0xfc, 0x57, 0xcf, 0xa8, 0xf8, 0x9f, 0xdc, 0xff, 0xd1, 0xba, 0x4a, 0xb3, + 0xd9, 0xae, 0x52, 0x41, 0x4d, 0x3d, 0x77, 0xd2, 0x9a, 0xba, 0x5e, 0x58, 0x53, 0x7b, 0x85, 0x76, + 0xdc, 0x10, 0xe2, 0xfe, 0xb6, 0xae, 0x81, 0x13, 0x75, 0xed, 0x34, 0xd5, 0x35, 0x3c, 0xd1, 0xea, + 0xfa, 0x83, 0x4c, 0xb5, 0x2c, 0xfb, 0x55, 0xaf, 0x9c, 0xec, 0x4c, 0x53, 0xea, 0xe6, 0xff, 0xb9, + 0x7a, 0xf0, 0xe7, 0xa2, 0x0c, 0xa0, 0x41, 0x2a, 0x83, 0x24, 0x5b, 0xe2, 0x71, 0x88, 0x67, 0x28, + 0xca, 0x69, 0xf1, 0x31, 0x7a, 0x1e, 0xaa, 0x5c, 0xc8, 0xaa, 0x4e, 0xbb, 0xa4, 0xcb, 0x93, 0xdf, + 0xc4, 0x26, 0xa5, 0x0f, 0x28, 0xb1, 0x2d, 0x81, 0x84, 0xde, 0x80, 0x46, 0xa2, 0xf8, 0xca, 0xb2, + 0xae, 0xea, 0x2b, 0x12, 0x3b, 0x89, 0x97, 0xa5, 0xe8, 0x7c, 0x6d, 0xcf, 0x09, 0x89, 0x2d, 0xaa, + 0x98, 0xda, 0xf8, 0xda, 0x5b, 0xf1, 0xc7, 0x64, 0x6d, 0x82, 0x8e, 0xd6, 0x61, 0x56, 0x36, 0xf8, + 0x84, 0x05, 0x35, 0x37, 0x2e, 0x8f, 0x3b, 0xd3, 0x78, 0x95, 0x42, 0x34, 0xff, 0x54, 0x82, 0xa7, + 0x53, 0x85, 0x88, 0xad, 0x29, 0x2e, 0x24, 0xbf, 0xf9, 0x88, 0x7b, 0x1d, 0x16, 0x44, 0xe5, 0x9a, + 0xf6, 0xf9, 0x64, 0xcb, 0x39, 0x07, 0x35, 0x7f, 0x57, 0x82, 0x67, 0xc7, 0xcf, 0xb1, 0x35, 0xc0, + 0x21, 0x4b, 0xae, 0xf7, 0x2c, 0xce, 0x12, 0x07, 0xbc, 0x72, 0x1a, 0xf0, 0x32, 0xe7, 0xab, 0x64, + 0xcf, 0x67, 0xfe, 0xa1, 0x0c, 0x4d, 0x4d, 0x81, 0x8a, 0x02, 0x26, 0xcf, 0x9b, 0x85, 0xde, 0x8a, + 0x5e, 0x85, 0x08, 0x0a, 0x0d, 0x4b, 0x83, 0xa0, 0x21, 0x00, 0xc5, 0x21, 0xf6, 0x08, 0x23, 0x21, + 0xf7, 0xe4, 0xdc, 0xe2, 0xef, 0x9e, 0xde, 0xbb, 0xec, 0xc7, 0x34, 0x2d, 0x8d, 0x3c, 0x4f, 0xfc, + 0xc5, 0xd6, 0x91, 0xf2, 0xdf, 0x6a, 0x86, 0x3e, 0x87, 0x85, 0x03, 0xc7, 0x25, 0xfb, 0x29, 0x23, + 0xb3, 0x82, 0x91, 0xfb, 0xa7, 0x67, 0xe4, 0x8e, 0x4e, 0xd7, 0xca, 0x6d, 0x63, 0xde, 0x84, 0xa5, + 0xbc, 0x3d, 0x71, 0x26, 0x1d, 0x0f, 0xf7, 0x13, 0x69, 0xa9, 0x99, 0x89, 0x60, 0x29, 0x6f, 0x3f, + 0xe6, 0x3f, 0xca, 0x70, 0x31, 0x21, 0xb7, 0xe9, 0xfb, 0xc1, 0xc8, 0xb7, 0x45, 0x01, 0x57, 0x78, + 0x17, 0x17, 0xa0, 0xc6, 0x1c, 0xe6, 0x26, 0x89, 0x8f, 0x98, 0xf0, 0xd8, 0xc5, 0x82, 0xc0, 0x65, + 0x0e, 0x55, 0x17, 0x1c, 0x4f, 0xe5, 0xdd, 0x8b, 0x9a, 0xb0, 0x27, 0x3c, 0x41, 0xdd, 0x4a, 0xe6, + 0xfc, 0x1b, 0xcf, 0x6a, 0x44, 0x35, 0x24, 0x85, 0x99, 0xcc, 0x85, 0xde, 0x07, 0xae, 0x4b, 0x6c, + 0x2e, 0x0e, 0xad, 0x5e, 0xca, 0x41, 0x45, 0x1d, 0xc6, 0x42, 0xc7, 0xef, 0xab, 0x6a, 0x49, 0xcd, + 0x38, 0x9f, 0x38, 0x0c, 0xf1, 0x91, 0x51, 0x17, 0x02, 0x90, 0x13, 0xf4, 0x16, 0x54, 0x3c, 0x4c, + 0x55, 0xa0, 0xbb, 0x99, 0xf1, 0x0e, 0x45, 0x12, 0x68, 0xef, 0x61, 0x2a, 0x23, 0x01, 0x5f, 0xd6, + 0x7a, 0x95, 0x57, 0xeb, 0xf4, 0xeb, 0xa7, 0x84, 0x9f, 0xc2, 0xb9, 0x8c, 0xf3, 0x41, 0x1f, 0xc1, + 0x4a, 0xaa, 0x51, 0xfa, 0x86, 0x2a, 0x09, 0x7c, 0xfa, 0x58, 0xce, 0xac, 0x09, 0x04, 0xcc, 0xcf, + 0x60, 0x99, 0xab, 0x8c, 0x30, 0xfc, 0x33, 0x2a, 0x6d, 0xde, 0x84, 0x46, 0xb2, 0x65, 0xa1, 0xce, + 0xb4, 0xa0, 0x7e, 0x18, 0x97, 0x84, 0xb2, 0xb6, 0x49, 0xe6, 0xe6, 0x26, 0x20, 0x9d, 0x5f, 0x15, + 0x81, 0x9e, 0xcf, 0x26, 0xc5, 0x17, 0xf3, 0xe1, 0x46, 0xa0, 0xc7, 0x39, 0xf1, 0xdf, 0xcb, 0xb0, + 0xb8, 0xed, 0x88, 0xc6, 0xdd, 0x19, 0x39, 0xb9, 0x9b, 0xb0, 0x14, 0x8d, 0xba, 0x5e, 0xd0, 0x1b, + 0xb9, 0x44, 0x25, 0x05, 0x2a, 0xd2, 0x8f, 0xc1, 0xa7, 0x39, 0xbf, 0xa4, 0x49, 0x53, 0xd5, 0x9a, + 0x34, 0x6f, 0xc1, 0xe5, 0x7b, 0xe4, 0x73, 0x75, 0x9e, 0x6d, 0x37, 0xe8, 0x76, 0x1d, 0xbf, 0x1f, + 0x6f, 0x52, 0x13, 0x9b, 0x4c, 0x46, 0x28, 0x4a, 0x15, 0x67, 0x8b, 0x53, 0xc5, 0xa4, 0xd9, 0xb0, + 0x25, 0xca, 0x78, 0x95, 0x51, 0x66, 0x60, 0xe6, 0xcf, 0x4a, 0xb0, 0x94, 0x4a, 0x56, 0xdd, 0xcd, + 0x6b, 0xd2, 0x86, 0xe4, 0xcd, 0x3c, 0xab, 0xdf, 0x4c, 0x1e, 0xf5, 0xdf, 0x37, 0x9f, 0x79, 0xdd, + 0x7c, 0x7e, 0x59, 0x86, 0x8b, 0xdb, 0x0e, 0x8b, 0x1d, 0x97, 0xf3, 0xdf, 0x76, 0xcb, 0x05, 0x77, + 0x52, 0x3d, 0xd9, 0x9d, 0xd4, 0x0a, 0xee, 0xa4, 0x0d, 0x2b, 0x79, 0x61, 0xa8, 0x8b, 0xb9, 0x00, + 0x35, 0x2a, 0x5e, 0x5b, 0x64, 0x5f, 0x41, 0x4e, 0xcc, 0x9f, 0xce, 0xc1, 0xb5, 0x0f, 0x68, 0x0f, + 0xb3, 0xa4, 0x91, 0x79, 0x27, 0x08, 0xc5, 0x73, 0xcb, 0xd9, 0x48, 0x31, 0xf7, 0x24, 0x5e, 0x9e, + 0xfa, 0x24, 0x5e, 0x99, 0xf2, 0x24, 0x5e, 0x3d, 0xd1, 0x93, 0x78, 0xed, 0xcc, 0x9e, 0xc4, 0xc7, + 0x6b, 0xad, 0xd9, 0xc2, 0x5a, 0xeb, 0xa3, 0x4c, 0x3d, 0x32, 0x27, 0xcc, 0xe6, 0x5b, 0xba, 0xd9, + 0x4c, 0xbd, 0x9d, 0xa9, 0x6f, 0x79, 0xb9, 0x97, 0xe4, 0xfa, 0xb1, 0x2f, 0xc9, 0x8d, 0xf1, 0x97, + 0xe4, 0xe2, 0xc7, 0x48, 0x98, 0xf8, 0x18, 0x79, 0x1d, 0x16, 0xa2, 0x23, 0xdf, 0x26, 0xbd, 0xa4, + 0xbd, 0xdd, 0x94, 0xc7, 0xce, 0x42, 0x33, 0x16, 0x31, 0x9f, 0xb3, 0x88, 0x44, 0x53, 0xcf, 0x69, + 0x9a, 0x5a, 0x64, 0x27, 0x0b, 0x13, 0xcb, 0xdc, 0xdc, 0x3b, 0xe1, 0x62, 0xd1, 0x3b, 0xe1, 0x7f, + 0x4e, 0xb1, 0xf5, 0x21, 0xac, 0x4e, 0xba, 0x65, 0x65, 0xbc, 0x06, 0xcc, 0xd9, 0x03, 0xec, 0xf7, + 0x45, 0x5b, 0x50, 0x54, 0xff, 0x6a, 0x3a, 0xad, 0x3a, 0x30, 0x7f, 0x5d, 0x86, 0x8b, 0x5b, 0x02, + 0x2f, 0xff, 0x94, 0xa3, 0x19, 0x55, 0x69, 0x8a, 0x51, 0x8d, 0xf5, 0xb5, 0x6f, 0xc0, 0xa2, 0x3d, + 0x0a, 0x43, 0x9e, 0x62, 0x64, 0xfd, 0x59, 0x1e, 0xcc, 0xdd, 0x23, 0xe5, 0x8c, 0xe8, 0x2f, 0x1d, + 0xd2, 0x46, 0xc7, 0xe0, 0xe9, 0x85, 0xd7, 0xf4, 0x0b, 0x8f, 0x1d, 0xcf, 0xec, 0x13, 0x49, 0x4b, + 0x5e, 0x86, 0x95, 0xbc, 0x68, 0x8e, 0x7f, 0xc0, 0xd9, 0xf8, 0x6d, 0x13, 0x96, 0xd3, 0x3a, 0x8a, + 0xff, 0x75, 0x6c, 0x82, 0xee, 0xc3, 0x52, 0xfc, 0x52, 0x9d, 0xbc, 0xb0, 0x4c, 0x7b, 0x22, 0x6d, + 0x5d, 0x2d, 0xfe, 0x28, 0x19, 0x30, 0x67, 0x90, 0x0d, 0x97, 0xf3, 0x04, 0xd3, 0xd7, 0xd8, 0x67, + 0xa6, 0x50, 0x4e, 0xb0, 0x8e, 0xdb, 0xe2, 0x46, 0x09, 0x7d, 0x04, 0x0b, 0xd9, 0x37, 0x43, 0x94, + 0x49, 0x2c, 0x0b, 0x9f, 0x31, 0x5b, 0xe6, 0x34, 0x94, 0x84, 0xff, 0x4f, 0xb8, 0x61, 0x65, 0x9e, + 0xc7, 0x90, 0x99, 0xed, 0xb1, 0x14, 0x3d, 0x30, 0xb6, 0xfe, 0x6f, 0x2a, 0x4e, 0x42, 0xfd, 0x4d, + 0xa8, 0xc7, 0xdd, 0xf9, 0xac, 0x98, 0x73, 0x3d, 0xfb, 0xd6, 0x52, 0x96, 0xde, 0x41, 0x64, 0xce, + 0xa0, 0xb7, 0xe5, 0xe2, 0x4d, 0x4a, 0x0b, 0x16, 0x6b, 0x3d, 0xe9, 0xd6, 0xf9, 0x82, 0x3e, 0xb0, + 0x39, 0x83, 0xbe, 0x03, 0x4d, 0x3e, 0xda, 0x57, 0xbf, 0x14, 0x5a, 0x69, 0xcb, 0x1f, 0xa6, 0xb5, + 0xe3, 0x1f, 0xa6, 0xb5, 0x6f, 0x7b, 0x94, 0x1d, 0xb5, 0x0a, 0x1a, 0xb5, 0x8a, 0xc0, 0x27, 0x70, + 0x6e, 0x9b, 0xb0, 0xb4, 0xaf, 0x82, 0x9e, 0x3d, 0x51, 0xf7, 0xa9, 0x65, 0xe6, 0xd1, 0xc6, 0x5b, + 0x33, 0xe6, 0x0c, 0xfa, 0x55, 0x09, 0xce, 0x6f, 0x13, 0x96, 0xef, 0x54, 0xa0, 0x17, 0x8b, 0x37, + 0x99, 0xd0, 0xd1, 0x68, 0xdd, 0x3b, 0xad, 0xb5, 0x65, 0xc9, 0x9a, 0x33, 0xe8, 0x37, 0x25, 0xb8, + 0xa4, 0x31, 0xa6, 0xb7, 0x1e, 0xd0, 0xfa, 0x74, 0xe6, 0x0a, 0xda, 0x14, 0xad, 0x77, 0x4f, 0xf9, + 0x03, 0x30, 0x8d, 0xa4, 0x39, 0x83, 0xf6, 0xc5, 0x9d, 0xa4, 0x95, 0x06, 0xba, 0x56, 0x58, 0x52, + 0x24, 0xbb, 0xaf, 0x4e, 0xfa, 0x9c, 0xdc, 0xc3, 0xbb, 0xd0, 0xdc, 0x26, 0x2c, 0x4e, 0x79, 0xb3, + 0x9a, 0x96, 0xab, 0x46, 0xb2, 0xa6, 0x9a, 0xcf, 0x92, 0x85, 0xc6, 0x2c, 0x4b, 0x5a, 0x5a, 0x5a, + 0x97, 0xb5, 0xd5, 0xc2, 0xfc, 0x37, 0xab, 0x31, 0xc5, 0x59, 0xa1, 0x39, 0x83, 0x3e, 0x83, 0x95, + 0xe2, 0xe0, 0x83, 0x9e, 0x3b, 0x71, 0x1a, 0xd2, 0xba, 0x79, 0x12, 0xd4, 0xdc, 0x81, 0xb2, 0xee, + 0x37, 0x7b, 0xa0, 0xc2, 0xa8, 0x95, 0x3d, 0x50, 0xb1, 0xf7, 0x36, 0x67, 0xde, 0xd9, 0xfc, 0xcb, + 0xa3, 0xd5, 0xd2, 0x5f, 0x1f, 0xad, 0x96, 0xfe, 0xf9, 0x68, 0xb5, 0xf4, 0xf1, 0x4b, 0xc7, 0xfc, + 0x0c, 0x55, 0xfb, 0xcd, 0x2c, 0xa6, 0x8e, 0xed, 0x3a, 0xc4, 0x67, 0xdd, 0x59, 0x61, 0xcd, 0x2f, + 0xfd, 0x2b, 0x00, 0x00, 0xff, 0xff, 0x12, 0x57, 0x95, 0x3b, 0x52, 0x2b, 0x00, 0x00, +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn // This is a compile-time assertion to ensure that this generated file // is compatible with the grpc package it is being compiled against. @@ -2670,6 +3083,7 @@ type RepoServerServiceClient interface { GetGitDirectories(ctx context.Context, in *GitDirectoriesRequest, opts ...grpc.CallOption) (*GitDirectoriesResponse, error) // UpdateRevisionForPaths will compare two revisions and update the cache with the new revision if no changes are detected in the provided paths UpdateRevisionForPaths(ctx context.Context, in *UpdateRevisionForPathsRequest, opts ...grpc.CallOption) (*UpdateRevisionForPathsResponse, error) + GetChangeRevision(ctx context.Context, in *ChangeRevisionRequest, opts ...grpc.CallOption) (*ChangeRevisionResponse, error) } type repoServerServiceClient struct { @@ -2831,6 +3245,15 @@ func (c *repoServerServiceClient) UpdateRevisionForPaths(ctx context.Context, in return out, nil } +func (c *repoServerServiceClient) GetChangeRevision(ctx context.Context, in *ChangeRevisionRequest, opts ...grpc.CallOption) (*ChangeRevisionResponse, error) { + out := new(ChangeRevisionResponse) + err := c.cc.Invoke(ctx, "/repository.RepoServerService/GetChangeRevision", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // RepoServerServiceServer is the server API for RepoServerService service. type RepoServerServiceServer interface { // GenerateManifest generates manifest for application in specified repo name and revision @@ -2861,6 +3284,7 @@ type RepoServerServiceServer interface { GetGitDirectories(context.Context, *GitDirectoriesRequest) (*GitDirectoriesResponse, error) // UpdateRevisionForPaths will compare two revisions and update the cache with the new revision if no changes are detected in the provided paths UpdateRevisionForPaths(context.Context, *UpdateRevisionForPathsRequest) (*UpdateRevisionForPathsResponse, error) + GetChangeRevision(context.Context, *ChangeRevisionRequest) (*ChangeRevisionResponse, error) } // UnimplementedRepoServerServiceServer can be embedded to have forward compatible implementations. @@ -2909,6 +3333,9 @@ func (*UnimplementedRepoServerServiceServer) GetGitDirectories(ctx context.Conte func (*UnimplementedRepoServerServiceServer) UpdateRevisionForPaths(ctx context.Context, req *UpdateRevisionForPathsRequest) (*UpdateRevisionForPathsResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method UpdateRevisionForPaths not implemented") } +func (*UnimplementedRepoServerServiceServer) GetChangeRevision(ctx context.Context, req *ChangeRevisionRequest) (*ChangeRevisionResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetChangeRevision not implemented") +} func RegisterRepoServerServiceServer(s *grpc.Server, srv RepoServerServiceServer) { s.RegisterService(&_RepoServerService_serviceDesc, srv) @@ -3174,6 +3601,24 @@ func _RepoServerService_UpdateRevisionForPaths_Handler(srv interface{}, ctx cont return interceptor(ctx, in, info, handler) } +func _RepoServerService_GetChangeRevision_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ChangeRevisionRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(RepoServerServiceServer).GetChangeRevision(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/repository.RepoServerService/GetChangeRevision", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(RepoServerServiceServer).GetChangeRevision(ctx, req.(*ChangeRevisionRequest)) + } + return interceptor(ctx, in, info, handler) +} + var _RepoServerService_serviceDesc = grpc.ServiceDesc{ ServiceName: "repository.RepoServerService", HandlerType: (*RepoServerServiceServer)(nil), @@ -3230,6 +3675,10 @@ var _RepoServerService_serviceDesc = grpc.ServiceDesc{ MethodName: "UpdateRevisionForPaths", Handler: _RepoServerService_UpdateRevisionForPaths_Handler, }, + { + MethodName: "GetChangeRevision", + Handler: _RepoServerService_GetChangeRevision_Handler, + }, }, Streams: []grpc.StreamDesc{ { @@ -3265,6 +3714,20 @@ func (m *ManifestRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + if m.ApplicationMetadata != nil { + { + size, err := m.ApplicationMetadata.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintRepository(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0xe2 + } if len(m.InstallationID) > 0 { i -= len(m.InstallationID) copy(dAtA[i:], m.InstallationID) @@ -3903,7 +4366,7 @@ func (m *ResolveRevisionResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) return len(dAtA) - i, nil } -func (m *ManifestResponse) Marshal() (dAtA []byte, err error) { +func (m *Manifest) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -3913,12 +4376,12 @@ func (m *ManifestResponse) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *ManifestResponse) MarshalTo(dAtA []byte) (int, error) { +func (m *Manifest) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *ManifestResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *Manifest) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int @@ -3927,63 +4390,84 @@ func (m *ManifestResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } - if len(m.Commands) > 0 { - for iNdEx := len(m.Commands) - 1; iNdEx >= 0; iNdEx-- { - i -= len(m.Commands[iNdEx]) - copy(dAtA[i:], m.Commands[iNdEx]) - i = encodeVarintRepository(dAtA, i, uint64(len(m.Commands[iNdEx]))) - i-- - dAtA[i] = 0x42 - } + if m.Line != 0 { + i = encodeVarintRepository(dAtA, i, uint64(m.Line)) + i-- + dAtA[i] = 0x20 } - if len(m.VerifyResult) > 0 { - i -= len(m.VerifyResult) - copy(dAtA[i:], m.VerifyResult) - i = encodeVarintRepository(dAtA, i, uint64(len(m.VerifyResult))) + if len(m.Path) > 0 { + i -= len(m.Path) + copy(dAtA[i:], m.Path) + i = encodeVarintRepository(dAtA, i, uint64(len(m.Path))) i-- - dAtA[i] = 0x3a + dAtA[i] = 0x1a } - if len(m.SourceType) > 0 { - i -= len(m.SourceType) - copy(dAtA[i:], m.SourceType) - i = encodeVarintRepository(dAtA, i, uint64(len(m.SourceType))) + if len(m.RawManifest) > 0 { + i -= len(m.RawManifest) + copy(dAtA[i:], m.RawManifest) + i = encodeVarintRepository(dAtA, i, uint64(len(m.RawManifest))) i-- - dAtA[i] = 0x32 + dAtA[i] = 0x12 } - if len(m.Revision) > 0 { - i -= len(m.Revision) - copy(dAtA[i:], m.Revision) - i = encodeVarintRepository(dAtA, i, uint64(len(m.Revision))) + if len(m.CompiledManifest) > 0 { + i -= len(m.CompiledManifest) + copy(dAtA[i:], m.CompiledManifest) + i = encodeVarintRepository(dAtA, i, uint64(len(m.CompiledManifest))) i-- - dAtA[i] = 0x22 + dAtA[i] = 0xa } - if len(m.Server) > 0 { - i -= len(m.Server) - copy(dAtA[i:], m.Server) - i = encodeVarintRepository(dAtA, i, uint64(len(m.Server))) + return len(dAtA) - i, nil +} + +func (m *Dependencies) 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 *Dependencies) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Dependencies) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if len(m.Requirements) > 0 { + i -= len(m.Requirements) + copy(dAtA[i:], m.Requirements) + i = encodeVarintRepository(dAtA, i, uint64(len(m.Requirements))) i-- dAtA[i] = 0x1a } - if len(m.Namespace) > 0 { - i -= len(m.Namespace) - copy(dAtA[i:], m.Namespace) - i = encodeVarintRepository(dAtA, i, uint64(len(m.Namespace))) + if len(m.Deps) > 0 { + i -= len(m.Deps) + copy(dAtA[i:], m.Deps) + i = encodeVarintRepository(dAtA, i, uint64(len(m.Deps))) i-- dAtA[i] = 0x12 } - if len(m.Manifests) > 0 { - for iNdEx := len(m.Manifests) - 1; iNdEx >= 0; iNdEx-- { - i -= len(m.Manifests[iNdEx]) - copy(dAtA[i:], m.Manifests[iNdEx]) - i = encodeVarintRepository(dAtA, i, uint64(len(m.Manifests[iNdEx]))) - i-- - dAtA[i] = 0xa - } + if len(m.Lock) > 0 { + i -= len(m.Lock) + copy(dAtA[i:], m.Lock) + i = encodeVarintRepository(dAtA, i, uint64(len(m.Lock))) + i-- + dAtA[i] = 0xa } return len(dAtA) - i, nil } -func (m *ListRefsRequest) Marshal() (dAtA []byte, err error) { +func (m *ApplicationVersions) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -3993,12 +4477,12 @@ func (m *ListRefsRequest) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *ListRefsRequest) MarshalTo(dAtA []byte) (int, error) { +func (m *ApplicationVersions) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *ListRefsRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *ApplicationVersions) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int @@ -4007,9 +4491,9 @@ func (m *ListRefsRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } - if m.Repo != nil { + if m.Dependencies != nil { { - size, err := m.Repo.MarshalToSizedBuffer(dAtA[:i]) + size, err := m.Dependencies.MarshalToSizedBuffer(dAtA[:i]) if err != nil { return 0, err } @@ -4017,12 +4501,19 @@ func (m *ListRefsRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintRepository(dAtA, i, uint64(size)) } i-- + dAtA[i] = 0x12 + } + if len(m.AppVersion) > 0 { + i -= len(m.AppVersion) + copy(dAtA[i:], m.AppVersion) + i = encodeVarintRepository(dAtA, i, uint64(len(m.AppVersion))) + i-- dAtA[i] = 0xa } return len(dAtA) - i, nil } -func (m *Refs) Marshal() (dAtA []byte, err error) { +func (m *ManifestResponse) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -4032,12 +4523,193 @@ func (m *Refs) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *Refs) MarshalTo(dAtA []byte) (int, error) { +func (m *ManifestResponse) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *Refs) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *ManifestResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if len(m.Commands) > 0 { + for iNdEx := len(m.Commands) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Commands[iNdEx]) + copy(dAtA[i:], m.Commands[iNdEx]) + i = encodeVarintRepository(dAtA, i, uint64(len(m.Commands[iNdEx]))) + i-- + dAtA[i] = 0x6a + } + } + if len(m.SourcesManifestsStartingIdx) > 0 { + dAtA15 := make([]byte, len(m.SourcesManifestsStartingIdx)*10) + var j14 int + for _, num1 := range m.SourcesManifestsStartingIdx { + num := uint64(num1) + for num >= 1<<7 { + dAtA15[j14] = uint8(uint64(num)&0x7f | 0x80) + num >>= 7 + j14++ + } + dAtA15[j14] = uint8(num) + j14++ + } + i -= j14 + copy(dAtA[i:], dAtA15[:j14]) + i = encodeVarintRepository(dAtA, i, uint64(j14)) + i-- + dAtA[i] = 0x62 + } + if m.ApplicationVersions != nil { + { + size, err := m.ApplicationVersions.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintRepository(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x5a + } + if m.CommitDate != nil { + { + size, err := m.CommitDate.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintRepository(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x52 + } + if len(m.CommitAuthor) > 0 { + i -= len(m.CommitAuthor) + copy(dAtA[i:], m.CommitAuthor) + i = encodeVarintRepository(dAtA, i, uint64(len(m.CommitAuthor))) + i-- + dAtA[i] = 0x4a + } + if len(m.CommitMessage) > 0 { + i -= len(m.CommitMessage) + copy(dAtA[i:], m.CommitMessage) + i = encodeVarintRepository(dAtA, i, uint64(len(m.CommitMessage))) + i-- + dAtA[i] = 0x42 + } + if len(m.VerifyResult) > 0 { + i -= len(m.VerifyResult) + copy(dAtA[i:], m.VerifyResult) + i = encodeVarintRepository(dAtA, i, uint64(len(m.VerifyResult))) + i-- + dAtA[i] = 0x3a + } + if len(m.SourceType) > 0 { + i -= len(m.SourceType) + copy(dAtA[i:], m.SourceType) + i = encodeVarintRepository(dAtA, i, uint64(len(m.SourceType))) + i-- + dAtA[i] = 0x32 + } + if len(m.Revision) > 0 { + i -= len(m.Revision) + copy(dAtA[i:], m.Revision) + i = encodeVarintRepository(dAtA, i, uint64(len(m.Revision))) + i-- + dAtA[i] = 0x22 + } + if len(m.Server) > 0 { + i -= len(m.Server) + copy(dAtA[i:], m.Server) + i = encodeVarintRepository(dAtA, i, uint64(len(m.Server))) + i-- + dAtA[i] = 0x1a + } + if len(m.Namespace) > 0 { + i -= len(m.Namespace) + copy(dAtA[i:], m.Namespace) + i = encodeVarintRepository(dAtA, i, uint64(len(m.Namespace))) + i-- + dAtA[i] = 0x12 + } + if len(m.Manifests) > 0 { + for iNdEx := len(m.Manifests) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Manifests[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintRepository(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *ListRefsRequest) 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 *ListRefsRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ListRefsRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if m.Repo != nil { + { + size, err := m.Repo.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintRepository(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *Refs) 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 *Refs) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Refs) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int @@ -5498,6 +6170,116 @@ func (m *UpdateRevisionForPathsResponse) MarshalToSizedBuffer(dAtA []byte) (int, return len(dAtA) - i, nil } +func (m *ChangeRevisionRequest) 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 *ChangeRevisionRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ChangeRevisionRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if m.Repo != nil { + { + size, err := m.Repo.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintRepository(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x32 + } + if len(m.Paths) > 0 { + for iNdEx := len(m.Paths) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Paths[iNdEx]) + copy(dAtA[i:], m.Paths[iNdEx]) + i = encodeVarintRepository(dAtA, i, uint64(len(m.Paths[iNdEx]))) + i-- + dAtA[i] = 0x2a + } + } + if len(m.PreviousRevision) > 0 { + i -= len(m.PreviousRevision) + copy(dAtA[i:], m.PreviousRevision) + i = encodeVarintRepository(dAtA, i, uint64(len(m.PreviousRevision))) + i-- + dAtA[i] = 0x22 + } + if len(m.CurrentRevision) > 0 { + i -= len(m.CurrentRevision) + copy(dAtA[i:], m.CurrentRevision) + i = encodeVarintRepository(dAtA, i, uint64(len(m.CurrentRevision))) + i-- + dAtA[i] = 0x1a + } + if len(m.Namespace) > 0 { + i -= len(m.Namespace) + copy(dAtA[i:], m.Namespace) + i = encodeVarintRepository(dAtA, i, uint64(len(m.Namespace))) + i-- + dAtA[i] = 0x12 + } + if len(m.AppName) > 0 { + i -= len(m.AppName) + copy(dAtA[i:], m.AppName) + i = encodeVarintRepository(dAtA, i, uint64(len(m.AppName))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *ChangeRevisionResponse) 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 *ChangeRevisionResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ChangeRevisionResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if len(m.Revision) > 0 { + i -= len(m.Revision) + copy(dAtA[i:], m.Revision) + i = encodeVarintRepository(dAtA, i, uint64(len(m.Revision))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + func encodeVarintRepository(dAtA []byte, offset int, v uint64) int { offset -= sovRepository(v) base := offset @@ -5630,6 +6412,10 @@ func (m *ManifestRequest) Size() (n int) { if l > 0 { n += 2 + l + sovRepository(uint64(l)) } + if m.ApplicationMetadata != nil { + l = m.ApplicationMetadata.Size() + n += 2 + l + sovRepository(uint64(l)) + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -5800,17 +6586,88 @@ func (m *ResolveRevisionResponse) Size() (n int) { return n } -func (m *ManifestResponse) Size() (n int) { +func (m *Manifest) Size() (n int) { if m == nil { return 0 } var l int _ = l - if len(m.Manifests) > 0 { - for _, s := range m.Manifests { - l = len(s) - n += 1 + l + sovRepository(uint64(l)) - } + l = len(m.CompiledManifest) + if l > 0 { + n += 1 + l + sovRepository(uint64(l)) + } + l = len(m.RawManifest) + if l > 0 { + n += 1 + l + sovRepository(uint64(l)) + } + l = len(m.Path) + if l > 0 { + n += 1 + l + sovRepository(uint64(l)) + } + if m.Line != 0 { + n += 1 + sovRepository(uint64(m.Line)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *Dependencies) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Lock) + if l > 0 { + n += 1 + l + sovRepository(uint64(l)) + } + l = len(m.Deps) + if l > 0 { + n += 1 + l + sovRepository(uint64(l)) + } + l = len(m.Requirements) + if l > 0 { + n += 1 + l + sovRepository(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *ApplicationVersions) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.AppVersion) + if l > 0 { + n += 1 + l + sovRepository(uint64(l)) + } + if m.Dependencies != nil { + l = m.Dependencies.Size() + n += 1 + l + sovRepository(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *ManifestResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Manifests) > 0 { + for _, e := range m.Manifests { + l = e.Size() + n += 1 + l + sovRepository(uint64(l)) + } } l = len(m.Namespace) if l > 0 { @@ -5832,6 +6689,29 @@ func (m *ManifestResponse) Size() (n int) { if l > 0 { n += 1 + l + sovRepository(uint64(l)) } + l = len(m.CommitMessage) + if l > 0 { + n += 1 + l + sovRepository(uint64(l)) + } + l = len(m.CommitAuthor) + if l > 0 { + n += 1 + l + sovRepository(uint64(l)) + } + if m.CommitDate != nil { + l = m.CommitDate.Size() + n += 1 + l + sovRepository(uint64(l)) + } + if m.ApplicationVersions != nil { + l = m.ApplicationVersions.Size() + n += 1 + l + sovRepository(uint64(l)) + } + if len(m.SourcesManifestsStartingIdx) > 0 { + l = 0 + for _, e := range m.SourcesManifestsStartingIdx { + l += sovRepository(uint64(e)) + } + n += 1 + sovRepository(uint64(l)) + l + } if len(m.Commands) > 0 { for _, s := range m.Commands { l = len(s) @@ -6518,6 +7398,60 @@ func (m *UpdateRevisionForPathsResponse) Size() (n int) { return n } +func (m *ChangeRevisionRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.AppName) + if l > 0 { + n += 1 + l + sovRepository(uint64(l)) + } + l = len(m.Namespace) + if l > 0 { + n += 1 + l + sovRepository(uint64(l)) + } + l = len(m.CurrentRevision) + if l > 0 { + n += 1 + l + sovRepository(uint64(l)) + } + l = len(m.PreviousRevision) + if l > 0 { + n += 1 + l + sovRepository(uint64(l)) + } + if len(m.Paths) > 0 { + for _, s := range m.Paths { + l = len(s) + n += 1 + l + sovRepository(uint64(l)) + } + } + if m.Repo != nil { + l = m.Repo.Size() + n += 1 + l + sovRepository(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *ChangeRevisionResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Revision) + if l > 0 { + n += 1 + l + sovRepository(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + func sovRepository(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -7475,6 +8409,42 @@ func (m *ManifestRequest) Unmarshal(dAtA []byte) error { } m.InstallationID = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 28: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ApplicationMetadata", 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.ApplicationMetadata == nil { + m.ApplicationMetadata = &v1.ObjectMeta{} + } + if err := m.ApplicationMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipRepository(dAtA[iNdEx:]) @@ -8287,7 +9257,7 @@ func (m *ResolveRevisionResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *ManifestResponse) Unmarshal(dAtA []byte) error { +func (m *Manifest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -8310,15 +9280,15 @@ func (m *ManifestResponse) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: ManifestResponse: wiretype end group for non-group") + return fmt.Errorf("proto: Manifest: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: ManifestResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: Manifest: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Manifests", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field CompiledManifest", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -8346,11 +9316,11 @@ func (m *ManifestResponse) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Manifests = append(m.Manifests, string(dAtA[iNdEx:postIndex])) + m.CompiledManifest = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Namespace", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field RawManifest", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -8378,11 +9348,11 @@ func (m *ManifestResponse) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Namespace = string(dAtA[iNdEx:postIndex]) + m.RawManifest = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Server", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Path", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -8410,13 +9380,13 @@ func (m *ManifestResponse) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Server = string(dAtA[iNdEx:postIndex]) + m.Path = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Revision", wireType) + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Line", wireType) } - var stringLen uint64 + m.Line = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowRepository @@ -8426,27 +9396,65 @@ func (m *ManifestResponse) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + m.Line |= int32(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthRepository + default: + iNdEx = preIndex + skippy, err := skipRepository(dAtA[iNdEx:]) + if err != nil { + return err } - postIndex := iNdEx + intStringLen - if postIndex < 0 { + if (skippy < 0) || (iNdEx+skippy) < 0 { return ErrInvalidLengthRepository } - if postIndex > l { + if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF } - m.Revision = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 6: + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Dependencies) 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 ErrIntOverflowRepository + } + 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: Dependencies: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Dependencies: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field SourceType", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Lock", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -8474,11 +9482,11 @@ func (m *ManifestResponse) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.SourceType = string(dAtA[iNdEx:postIndex]) + m.Lock = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 7: + case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field VerifyResult", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Deps", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -8506,11 +9514,11 @@ func (m *ManifestResponse) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.VerifyResult = string(dAtA[iNdEx:postIndex]) + m.Deps = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 8: + case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Commands", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Requirements", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -8538,7 +9546,7 @@ func (m *ManifestResponse) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Commands = append(m.Commands, string(dAtA[iNdEx:postIndex])) + m.Requirements = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex @@ -8562,7 +9570,7 @@ func (m *ManifestResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *ListRefsRequest) Unmarshal(dAtA []byte) error { +func (m *ApplicationVersions) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -8585,17 +9593,17 @@ func (m *ListRefsRequest) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: ListRefsRequest: wiretype end group for non-group") + return fmt.Errorf("proto: ApplicationVersions: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: ListRefsRequest: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: ApplicationVersions: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Repo", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field AppVersion", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowRepository @@ -8605,31 +9613,639 @@ func (m *ListRefsRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthRepository } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthRepository } if postIndex > l { return io.ErrUnexpectedEOF } - if m.Repo == nil { - m.Repo = &v1alpha1.Repository{} - } - if err := m.Repo.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.AppVersion = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipRepository(dAtA[iNdEx:]) + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Dependencies", 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.Dependencies == nil { + m.Dependencies = &Dependencies{} + } + if err := m.Dependencies.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipRepository(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthRepository + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ManifestResponse) 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 ErrIntOverflowRepository + } + 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: ManifestResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ManifestResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Manifests", 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 + } + m.Manifests = append(m.Manifests, &Manifest{}) + if err := m.Manifests[len(m.Manifests)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Namespace", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRepository + } + 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 ErrInvalidLengthRepository + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthRepository + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Namespace = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Server", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRepository + } + 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 ErrInvalidLengthRepository + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthRepository + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Server = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Revision", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRepository + } + 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 ErrInvalidLengthRepository + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthRepository + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Revision = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SourceType", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRepository + } + 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 ErrInvalidLengthRepository + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthRepository + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.SourceType = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field VerifyResult", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRepository + } + 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 ErrInvalidLengthRepository + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthRepository + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.VerifyResult = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field CommitMessage", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRepository + } + 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 ErrInvalidLengthRepository + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthRepository + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.CommitMessage = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 9: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field CommitAuthor", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRepository + } + 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 ErrInvalidLengthRepository + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthRepository + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.CommitAuthor = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 10: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field CommitDate", 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.CommitDate == nil { + m.CommitDate = &v1.Time{} + } + if err := m.CommitDate.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 11: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ApplicationVersions", 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.ApplicationVersions == nil { + m.ApplicationVersions = &ApplicationVersions{} + } + if err := m.ApplicationVersions.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 12: + if wireType == 0 { + var v int32 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRepository + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.SourcesManifestsStartingIdx = append(m.SourcesManifestsStartingIdx, v) + } else if wireType == 2 { + var packedLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRepository + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + packedLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if packedLen < 0 { + return ErrInvalidLengthRepository + } + postIndex := iNdEx + packedLen + if postIndex < 0 { + return ErrInvalidLengthRepository + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + var elementCount int + var count int + for _, integer := range dAtA[iNdEx:postIndex] { + if integer < 128 { + count++ + } + } + elementCount = count + if elementCount != 0 && len(m.SourcesManifestsStartingIdx) == 0 { + m.SourcesManifestsStartingIdx = make([]int32, 0, elementCount) + } + for iNdEx < postIndex { + var v int32 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRepository + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.SourcesManifestsStartingIdx = append(m.SourcesManifestsStartingIdx, v) + } + } else { + return fmt.Errorf("proto: wrong wireType = %d for field SourcesManifestsStartingIdx", wireType) + } + case 13: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Commands", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRepository + } + 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 ErrInvalidLengthRepository + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthRepository + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Commands = append(m.Commands, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipRepository(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthRepository + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ListRefsRequest) 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 ErrIntOverflowRepository + } + 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: ListRefsRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ListRefsRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Repo", 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.Repo == nil { + m.Repo = &v1alpha1.Repository{} + } + if err := m.Repo.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipRepository(dAtA[iNdEx:]) if err != nil { return err } @@ -12609,11 +14225,211 @@ func (m *UpdateRevisionForPathsRequest) Unmarshal(dAtA []byte) error { iNdEx += skippy } } - m.RefSources[mapkey] = mapvalue - iNdEx = postIndex - case 8: + m.RefSources[mapkey] = mapvalue + iNdEx = postIndex + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field KubeVersion", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRepository + } + 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 ErrInvalidLengthRepository + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthRepository + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.KubeVersion = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 9: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ApiVersions", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRepository + } + 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 ErrInvalidLengthRepository + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthRepository + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ApiVersions = append(m.ApiVersions, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + case 10: + 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 11: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SyncedRevision", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRepository + } + 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 ErrInvalidLengthRepository + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthRepository + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.SyncedRevision = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 12: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Revision", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRepository + } + 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 ErrInvalidLengthRepository + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthRepository + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Revision = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 13: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Paths", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRepository + } + 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 ErrInvalidLengthRepository + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthRepository + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Paths = append(m.Paths, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + case 14: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field NoRevisionCache", 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.NoRevisionCache = bool(v != 0) + case 15: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field KubeVersion", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field InstallationID", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -12641,11 +14457,82 @@ func (m *UpdateRevisionForPathsRequest) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.KubeVersion = string(dAtA[iNdEx:postIndex]) + m.InstallationID = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 9: + default: + iNdEx = preIndex + skippy, err := skipRepository(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthRepository + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *UpdateRevisionForPathsResponse) 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 ErrIntOverflowRepository + } + 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: UpdateRevisionForPathsResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: UpdateRevisionForPathsResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Changes", 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.Changes = bool(v != 0) + case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ApiVersions", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Revision", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -12673,13 +14560,64 @@ func (m *UpdateRevisionForPathsRequest) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.ApiVersions = append(m.ApiVersions, string(dAtA[iNdEx:postIndex])) + m.Revision = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 10: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field HasMultipleSources", wireType) + default: + iNdEx = preIndex + skippy, err := skipRepository(dAtA[iNdEx:]) + if err != nil { + return err } - var v int + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthRepository + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ChangeRevisionRequest) 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 ErrIntOverflowRepository + } + 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: ChangeRevisionRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ChangeRevisionRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AppName", wireType) + } + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowRepository @@ -12689,15 +14627,27 @@ func (m *UpdateRevisionForPathsRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - v |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - m.HasMultipleSources = bool(v != 0) - case 11: + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthRepository + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthRepository + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AppName = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field SyncedRevision", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Namespace", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -12725,11 +14675,11 @@ func (m *UpdateRevisionForPathsRequest) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.SyncedRevision = string(dAtA[iNdEx:postIndex]) + m.Namespace = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 12: + case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Revision", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field CurrentRevision", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -12757,11 +14707,11 @@ func (m *UpdateRevisionForPathsRequest) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Revision = string(dAtA[iNdEx:postIndex]) + m.CurrentRevision = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 13: + case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Paths", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field PreviousRevision", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -12789,13 +14739,13 @@ func (m *UpdateRevisionForPathsRequest) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Paths = append(m.Paths, string(dAtA[iNdEx:postIndex])) + m.PreviousRevision = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 14: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field NoRevisionCache", wireType) + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Paths", wireType) } - var v int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowRepository @@ -12805,17 +14755,29 @@ func (m *UpdateRevisionForPathsRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - v |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - m.NoRevisionCache = bool(v != 0) - case 15: + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthRepository + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthRepository + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Paths = append(m.Paths, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + case 6: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field InstallationID", 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 ErrIntOverflowRepository @@ -12825,23 +14787,27 @@ func (m *UpdateRevisionForPathsRequest) 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 ErrInvalidLengthRepository } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthRepository } if postIndex > l { return io.ErrUnexpectedEOF } - m.InstallationID = string(dAtA[iNdEx:postIndex]) + if m.Repo == nil { + m.Repo = &v1alpha1.Repository{} + } + if err := m.Repo.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex default: iNdEx = preIndex @@ -12865,7 +14831,7 @@ func (m *UpdateRevisionForPathsRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *UpdateRevisionForPathsResponse) Unmarshal(dAtA []byte) error { +func (m *ChangeRevisionResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -12888,33 +14854,13 @@ func (m *UpdateRevisionForPathsResponse) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: UpdateRevisionForPathsResponse: wiretype end group for non-group") + return fmt.Errorf("proto: ChangeRevisionResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: UpdateRevisionForPathsResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: ChangeRevisionResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Changes", 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.Changes = bool(v != 0) - case 2: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Revision", wireType) } diff --git a/reposerver/cache/cache.go b/reposerver/cache/cache.go index cdc16ea4ebb82..5b9c706b38e8d 100644 --- a/reposerver/cache/cache.go +++ b/reposerver/cache/cache.go @@ -30,10 +30,11 @@ var ( ) type Cache struct { - cache *cacheutil.Cache - repoCacheExpiration time.Duration - revisionCacheExpiration time.Duration - revisionCacheLockTimeout time.Duration + cache *cacheutil.Cache + repoCacheExpiration time.Duration + revisionCacheExpiration time.Duration + revisionCacheLockTimeout time.Duration + cfAppConfigCacheExpiration time.Duration } // ClusterRuntimeInfo holds cluster runtime information @@ -44,18 +45,20 @@ type ClusterRuntimeInfo interface { GetKubeVersion() string } -func NewCache(cache *cacheutil.Cache, repoCacheExpiration time.Duration, revisionCacheExpiration time.Duration, revisionCacheLockTimeout time.Duration) *Cache { - return &Cache{cache, repoCacheExpiration, revisionCacheExpiration, revisionCacheLockTimeout} +func NewCache(cache *cacheutil.Cache, repoCacheExpiration time.Duration, revisionCacheExpiration time.Duration, revisionCacheLockTimeout time.Duration, cfAppConfigCacheExpiration time.Duration) *Cache { + return &Cache{cache, repoCacheExpiration, revisionCacheExpiration, revisionCacheLockTimeout, cfAppConfigCacheExpiration} } func AddCacheFlagsToCmd(cmd *cobra.Command, opts ...cacheutil.Options) func() (*Cache, error) { var repoCacheExpiration time.Duration var revisionCacheExpiration time.Duration var revisionCacheLockTimeout time.Duration + var cfAppConfigCacheExpiration time.Duration cmd.Flags().DurationVar(&repoCacheExpiration, "repo-cache-expiration", env.ParseDurationFromEnv("ARGOCD_REPO_CACHE_EXPIRATION", 24*time.Hour, 0, math.MaxInt64), "Cache expiration for repo state, incl. app lists, app details, manifest generation, revision meta-data") cmd.Flags().DurationVar(&revisionCacheExpiration, "revision-cache-expiration", env.ParseDurationFromEnv("ARGOCD_RECONCILIATION_TIMEOUT", 3*time.Minute, 0, math.MaxInt64), "Cache expiration for cached revision") cmd.Flags().DurationVar(&revisionCacheLockTimeout, "revision-cache-lock-timeout", env.ParseDurationFromEnv("ARGOCD_REVISION_CACHE_LOCK_TIMEOUT", 10*time.Second, 0, math.MaxInt64), "Cache TTL for locks to prevent duplicate requests on revisions, set to 0 to disable") + cmd.Flags().DurationVar(&cfAppConfigCacheExpiration, "cf-app-config-cache-expiration", env.ParseDurationFromEnv("ARGOCD_CF_APP_CONFIG_CACHE_EXPIRATION", 3*time.Minute, 0, math.MaxInt64), "Cache expiration for Codefresh application configs") repoFactory := cacheutil.AddCacheFlagsToCmd(cmd, opts...) @@ -64,7 +67,7 @@ func AddCacheFlagsToCmd(cmd *cobra.Command, opts ...cacheutil.Options) func() (* if err != nil { return nil, fmt.Errorf("error adding cache flags to cmd: %w", err) } - return NewCache(cache, repoCacheExpiration, revisionCacheExpiration, revisionCacheLockTimeout), nil + return NewCache(cache, repoCacheExpiration, revisionCacheExpiration, revisionCacheLockTimeout, cfAppConfigCacheExpiration), nil } } diff --git a/reposerver/cache/cache_test.go b/reposerver/cache/cache_test.go index a42ac0a513239..73f3d27a8b438 100644 --- a/reposerver/cache/cache_test.go +++ b/reposerver/cache/cache_test.go @@ -33,7 +33,7 @@ type fixtures struct { func newFixtures() *fixtures { mockCache := mocks.NewMockRepoCache(&mocks.MockCacheOptions{RevisionCacheExpiration: 1 * time.Minute, RepoCacheExpiration: 1 * time.Minute}) newBaseCache := cacheutil.NewCache(mockCache.RedisClient) - baseCache := NewCache(newBaseCache, 1*time.Minute, 1*time.Minute, 10*time.Second) + baseCache := NewCache(newBaseCache, 1*time.Minute, 1*time.Minute, 10*time.Second, 1*time.Minute) return &fixtures{mockCache: mockCache, cache: &MockedCache{Cache: baseCache}} } @@ -146,7 +146,7 @@ func TestCache_GetAppDetails(t *testing.T) { mockCache := fixtures.mockCache // cache miss value := &apiclient.RepoAppDetailsResponse{} - emptyRefSources := map[string]*RefTarget{} + emptyRefSources := map[string]*appv1.RefTarget{} err := cache.GetAppDetails("my-revision", &ApplicationSource{}, emptyRefSources, value, "", nil) assert.Equal(t, ErrCacheMiss, err) res := &apiclient.RepoAppDetailsResponse{Type: "my-type"} @@ -179,14 +179,19 @@ func TestCachedManifestResponse_HashBehavior(t *testing.T) { 1*time.Minute, 1*time.Minute, 10*time.Second, + 1*time.Minute, ) response := apiclient.ManifestResponse{ Namespace: "default", Revision: "revision", - Manifests: []string{"sample-text"}, + Manifests: []*apiclient.Manifest{ + { + CompiledManifest: "sample-text", + }, + }, } - appSrc := &ApplicationSource{} + appSrc := &appv1.ApplicationSource{} appKey := "key" appValue := "value" @@ -285,7 +290,10 @@ func TestCachedManifestResponse_ShallowCopy(t *testing.T) { CacheEntryHash: "value", FirstFailureTimestamp: 1, ManifestResponse: &apiclient.ManifestResponse{ - Manifests: []string{"one", "two"}, + Manifests: []*apiclient.Manifest{ + {CompiledManifest: "one"}, + {CompiledManifest: "two"}, + }, }, MostRecentError: "error", NumberOfCachedResponsesReturned: 2, @@ -299,7 +307,10 @@ func TestCachedManifestResponse_ShallowCopy(t *testing.T) { CacheEntryHash: "diff-value", FirstFailureTimestamp: 1, ManifestResponse: &apiclient.ManifestResponse{ - Manifests: []string{"one", "two"}, + Manifests: []*apiclient.Manifest{ + {CompiledManifest: "one"}, + {CompiledManifest: "two"}, + }, }, MostRecentError: "error", NumberOfCachedResponsesReturned: 2, diff --git a/reposerver/cache/cf_cache.go b/reposerver/cache/cf_cache.go new file mode 100644 index 0000000000000..95e9059150c4a --- /dev/null +++ b/reposerver/cache/cf_cache.go @@ -0,0 +1,21 @@ +package cache + +import ( + "fmt" + + "github.com/argoproj/argo-cd/v2/pkg/codefresh" + cacheutil "github.com/argoproj/argo-cd/v2/util/cache" +) + +func CfAppConfigCacheKey(namespace, name string) string { + return fmt.Sprintf("cf_app_config:%s:%s", namespace, name) +} + +func (c *Cache) GetCfAppConfig(namespace, name string) (*codefresh.PromotionTemplate, error) { + item := &codefresh.PromotionTemplate{} + return item, c.cache.GetItem(CfAppConfigCacheKey(namespace, name), item) +} + +func (c *Cache) SetCfAppConfig(namespace, name string, item *codefresh.PromotionTemplate) error { + return c.cache.SetItem(CfAppConfigCacheKey(namespace, name), item, &cacheutil.CacheActionOpts{Expiration: c.cfAppConfigCacheExpiration, Delete: false}) +} diff --git a/reposerver/repository/app_version.go b/reposerver/repository/app_version.go new file mode 100644 index 0000000000000..8c59b9493bc88 --- /dev/null +++ b/reposerver/repository/app_version.go @@ -0,0 +1,180 @@ +package repository + +import ( + "encoding/json" + "fmt" + "os" + "path/filepath" + "reflect" + "strconv" + + "github.com/PaesslerAG/jsonpath" + log "github.com/sirupsen/logrus" + "gopkg.in/yaml.v2" + + "github.com/argoproj/argo-cd/v2/pkg/version_config_manager" +) + +type DependenciesMap struct { + Lock string `json:"helm/Chart.lock"` + Deps string `json:"helm/dependencies"` + Requirements string `json:"helm/requirements.yaml"` +} + +type Result struct { + AppVersion string `json:"appVersion"` + Dependencies DependenciesMap `json:"dependencies"` +} + +func parseVersionValue(jsonPathExpression string, jsonObj interface{}) string { + versionValue, err := jsonpath.Get(jsonPathExpression, jsonObj) + if err != nil { + log.Errorf("Can't get version from file. %v", err) + return "" + } + + var appVersion string + var conversionSuccess bool + if versionArray, ok := versionValue.([]interface{}); ok && len(versionArray) > 0 { + appVersion, conversionSuccess = versionArray[0].(string) + } else { + appVersion, conversionSuccess = versionValue.(string) + } + + if !conversionSuccess { + if versionValue == nil { + log.Info("Version value is not a string. Got: nil") + } else { + log.Infof("Version value is not a string. Got: %v", versionValue) + } + appVersion = "" + } + + return appVersion +} + +func getVersionFromFile(appPath, jsonPathExpression string) (*string, error) { + content, err := os.ReadFile(appPath) + if err != nil { + return nil, err + } + + log.Infof("AppVersion source content was read from %s", appPath) + + var obj interface{} + var jsonObj interface{} + + // Determine the file type and unmarshal accordingly + switch filepath.Ext(appPath) { + case ".yaml", ".yml": + if err := yaml.Unmarshal(content, &obj); err != nil { + return nil, err + } + // Convert YAML to Map[string]interface{} + jsonObj, err = convertToJSONCompatible(obj) + if err != nil { + return nil, err + } + case ".json": + if err := json.Unmarshal(content, &obj); err != nil { + return nil, err + } + jsonObj = obj + default: + return nil, fmt.Errorf("Unsupported file format of %s", appPath) + } + + appVersion := parseVersionValue(jsonPathExpression, jsonObj) + + log.Infof("Extracted appVersion: %s", appVersion) + return &appVersion, nil +} + +func convertToJSONCompatible(i interface{}) (interface{}, error) { + data, err := yaml.Marshal(i) + if err != nil { + return nil, err + } + var obj interface{} + if err := yaml.Unmarshal(data, &obj); err != nil { + return nil, err + } + + return convertMapKeysToString(obj) +} + +func convertMapKeysToString(obj interface{}) (interface{}, error) { + switch m := obj.(type) { + case map[interface{}]interface{}: + result := make(map[string]interface{}) + for k, v := range m { + strKey, ok := k.(string) + if !ok { + return nil, fmt.Errorf("Non-string key found in map: %v", k) + } + result[strKey], _ = convertMapKeysToString(v) + } + return result, nil + case []interface{}: + for i, v := range m { + var err error + m[i], err = convertMapKeysToString(v) + if err != nil { + return nil, err + } + } + return m, nil + case float64: + obj = strconv.FormatFloat(m, 'f', -1, 64) + case int: + obj = strconv.Itoa(m) + } + return obj, nil +} + +func readFileContent(result *Result, appPath, fileName, fieldName string) { + content, err := os.ReadFile(filepath.Join(appPath, fileName)) + if err == nil && content != nil { + v := reflect.ValueOf(result).Elem() + f := v.FieldByName("Dependencies").FieldByName(fieldName) + if f.IsValid() && f.CanSet() && f.Kind() == reflect.String { + f.SetString(string(content)) + } + } +} + +func getAppVersions(appPath string, versionConfig *version_config_manager.VersionConfig) (*Result, error) { + // Defaults + resourceName := version_config_manager.DefaultVersionSource + jsonPathExpression := version_config_manager.DefaultVersionPath + + if versionConfig != nil { + if versionConfig.ResourceName != "" { + resourceName = versionConfig.ResourceName + } + if versionConfig.JsonPath != "" { + jsonPathExpression = versionConfig.JsonPath + } + } + + // Get version of root + log.Infof("appVersion get from file: %s, jsonPath: %s", filepath.Join(appPath, resourceName), jsonPathExpression) + appVersion, err := getVersionFromFile(filepath.Join(appPath, resourceName), jsonPathExpression) + if err != nil { + log.Errorf("Error in getVersionFromFile. %v", err) + return nil, err + } + log.Infof("appVersion value: %v (appPath=%s)", *appVersion, appPath) + + result := &Result{ + AppVersion: *appVersion, + Dependencies: DependenciesMap{}, + } + + readFileContent(result, appPath, "Chart.lock", "Lock") + readFileContent(result, appPath, "Chart.yaml", "Deps") + readFileContent(result, appPath, "requirements.yaml", "Requirements") + + log.Infof("Return appVersion as: %v", result) + return result, nil +} diff --git a/reposerver/repository/app_version_parseVersionValue_test.go b/reposerver/repository/app_version_parseVersionValue_test.go new file mode 100644 index 0000000000000..d8c4a06409e43 --- /dev/null +++ b/reposerver/repository/app_version_parseVersionValue_test.go @@ -0,0 +1,178 @@ +package repository + +import ( + "bytes" + "strings" + "testing" + + log "github.com/sirupsen/logrus" +) + +// Correctly extracts version when jsonPathExpression matches a string value +func TestParseVersionValueWithString(t *testing.T) { + jsonObj := map[string]interface{}{ + "version": "1.0.0", + } + jsonPathExpression := "$.version" + expectedVersion := "1.0.0" + + actualVersion := parseVersionValue(jsonPathExpression, jsonObj) + + if actualVersion != expectedVersion { + t.Errorf("Expected version %s, but got %s", expectedVersion, actualVersion) + } +} + +// Handles non-string version values gracefully +func TestParseVersionValueWithNonString(t *testing.T) { + jsonObj := map[string]interface{}{ + "version": 123, + } + jsonPathExpression := "$.version" + expectedVersion := "" + + actualVersion := parseVersionValue(jsonPathExpression, jsonObj) + + if actualVersion != expectedVersion { + t.Errorf("Expected version %s, but got %s", expectedVersion, actualVersion) + } +} + +// Logs appropriate message when version value is non-string +func TestParseVersionValueWithNonString1(t *testing.T) { + jsonObj := map[string]interface{}{ + "version": 1.0, + } + jsonPathExpression := "$.version" + + // Capture log output + var logOutput bytes.Buffer + log.SetOutput(&logOutput) + + _ = parseVersionValue(jsonPathExpression, jsonObj) + + expectedLogMessage := "Version value is not a string. Got: 1" + if !strings.Contains(logOutput.String(), expectedLogMessage) { + t.Errorf("Expected log message containing '%s', but got '%s'", expectedLogMessage, logOutput.String()) + } +} + +// Correctly extracts version when jsonPathExpression matches an array with a string value +func TestParseVersionValueWithArray(t *testing.T) { + jsonObj := map[string]interface{}{ + "version": []interface{}{"1.0.0"}, + } + jsonPathExpression := "$.version" + expectedVersion := "1.0.0" + + actualVersion := parseVersionValue(jsonPathExpression, jsonObj) + + if actualVersion != expectedVersion { + t.Errorf("Expected version %s, but got %s", expectedVersion, actualVersion) + } +} + +// Returns empty string when jsonPathExpression does not match any value +func TestParseVersionValueWhenJsonPathExpressionDoesNotMatch(t *testing.T) { + jsonObj := map[string]interface{}{ + "version": "1.0.0", + } + jsonPathExpression := "$.nonexistent" + expectedVersion := "" + + actualVersion := parseVersionValue(jsonPathExpression, jsonObj) + + if actualVersion != expectedVersion { + t.Errorf("Expected version %s, but got %s", expectedVersion, actualVersion) + } +} + +// Handles nil jsonObj without crashing +func TestParseVersionValueWithNilJSONObj(t *testing.T) { + var jsonObj interface{} + jsonPathExpression := "$.version" + expectedVersion := "" + + actualVersion := parseVersionValue(jsonPathExpression, jsonObj) + + if actualVersion != expectedVersion { + t.Errorf("Expected version %s, but got %s", expectedVersion, actualVersion) + } +} + +// Handles empty jsonPathExpression without crashing +func TestParseVersionValueWithEmptyExpression(t *testing.T) { + jsonObj := map[string]interface{}{ + "version": "1.0.0", + } + jsonPathExpression := "" + expectedVersion := "" + + actualVersion := parseVersionValue(jsonPathExpression, jsonObj) + + if actualVersion != expectedVersion { + t.Errorf("Expected version %s, but got %s", expectedVersion, actualVersion) + } +} + +// Handles jsonPathExpression that matches an empty array +func TestParseVersionValueWithEmptyArray(t *testing.T) { + jsonObj := []interface{}{} + jsonPathExpression := "$.version" + expectedVersion := "" + + actualVersion := parseVersionValue(jsonPathExpression, jsonObj) + + if actualVersion != expectedVersion { + t.Errorf("Expected version %s, but got %s", expectedVersion, actualVersion) + } +} + +// Handles jsonPathExpression that matches a non-string array +func TestParseVersionValueWithNonStringArray(t *testing.T) { + jsonObj := map[string]interface{}{ + "version": []interface{}{1.0, 2.0, 3.0}, + } + jsonPathExpression := "$.version" + expectedVersion := "" + + actualVersion := parseVersionValue(jsonPathExpression, jsonObj) + + if actualVersion != expectedVersion { + t.Errorf("Expected version %s, but got %s", expectedVersion, actualVersion) + } +} + +// Handles jsonPathExpression that matches a nil value +func TestParseVersionValueWithNil(t *testing.T) { + jsonObj := map[string]interface{}{ + "version": nil, + } + jsonPathExpression := "$.version" + expectedVersion := "" + + actualVersion := parseVersionValue(jsonPathExpression, jsonObj) + + if actualVersion != expectedVersion { + t.Errorf("Expected version %s, but got %s", expectedVersion, actualVersion) + } +} + +// Logs appropriate message when version value is nil +func TestParseVersionValueWithNilVersion(t *testing.T) { + jsonObj := map[string]interface{}{ + "version": nil, + } + jsonPathExpression := "$.version" + + var buf bytes.Buffer + log.SetOutput(&buf) + + _ = parseVersionValue(jsonPathExpression, jsonObj) + + logOutput := buf.String() + expectedLog := "Version value is not a string. Got: nil" + if !strings.Contains(logOutput, expectedLog) { + t.Errorf("Expected log message: %s, but got: %s", expectedLog, logOutput) + } +} diff --git a/reposerver/repository/cf_repository.go b/reposerver/repository/cf_repository.go new file mode 100644 index 0000000000000..99eb62e5d0aef --- /dev/null +++ b/reposerver/repository/cf_repository.go @@ -0,0 +1,138 @@ +package repository + +import ( + goio "io" + "os" + "path/filepath" + + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/pkg/version_config_manager" + argopath "github.com/argoproj/argo-cd/v2/util/app/path" + "github.com/argoproj/argo-cd/v2/util/git" + "github.com/argoproj/argo-cd/v2/util/io" + "github.com/argoproj/argo-cd/v2/util/kustomize" + + log "github.com/sirupsen/logrus" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" +) + +type ( + CfOptions struct { + ApplicationVersioningEnabled bool + VersionConfig *version_config_manager.VersionConfig + GitClient git.Client + } +) + +func (s *Service) getCacheKeyWithKustomizeComponents( + revision string, + repo *v1alpha1.Repository, + source *v1alpha1.ApplicationSource, + settings operationSettings, + gitClient git.Client, +) (string, error) { + closer, err := s.repoLock.Lock(gitClient.Root(), revision, settings.allowConcurrent, func() (goio.Closer, error) { + return s.checkoutRevision(gitClient, revision, s.initConstants.SubmoduleEnabled) + }) + if err != nil { + return "", err + } + + defer io.Close(closer) + + appPath, err := argopath.Path(gitClient.Root(), source.Path) + if err != nil { + return "", err + } + + k := kustomize.NewKustomizeApp(gitClient.Root(), appPath, repo.GetGitCreds(s.gitCredsStore), repo.Repo, source.Kustomize.Version, "", "") + + resolveRevisionFunc := func(repoURL, revision string, creds git.Creds) (string, error) { + cloneRepo := *repo + cloneRepo.Repo = repoURL + _, res, err := s.newClientResolveRevision(&cloneRepo, revision) + return res, err + } + + return k.GetCacheKeyWithComponents(revision, source.Kustomize, resolveRevisionFunc) +} + +func (s *Service) getVersionConfig(appMetadata *metav1.ObjectMeta) *version_config_manager.VersionConfig { + if appMetadata == nil { + log.Infof("cfAppConfig. appMetadata is nil. Unable to retrieve version configuration.") + return nil + } + + var versionConfig *version_config_manager.VersionConfig + logCtx := log.WithFields(log.Fields{ + "namespace": appMetadata.Namespace, + "name": appMetadata.Name, + }) + if s.initConstants.CodefreshApplicationVersioningEnabled && s.initConstants.CodefreshUseApplicationConfiguration { + logCtx.Info("cfAppConfig. Getting version config") + versionConfig = s.GetVersionConfig(appMetadata) + if versionConfig != nil { + logCtx.WithFields(log.Fields{ + "configFile": versionConfig.ResourceName, + "jsonPath": versionConfig.JsonPath, + }).Infof("cfAppConfig. Version config found") + } else { + logCtx.Info("cfAppConfig. versionConfig is nil. Unable to retrieve version configuration.") + } + } else { + logCtx.Info("cfAppConfig. Flags for application versioning (CODEFRESH_APPLICATION_VERSIONING_ENABLED and CODEFRESH_USE_APPLICATION_CONFIGURATION) disabled. Skip getting application version config.") + } + + return versionConfig +} + +func (s *Service) GetVersionConfig(app *metav1.ObjectMeta) *version_config_manager.VersionConfig { + versionConfig, err := s.versionConfigManager.GetVersionConfig(app) + + if versionConfig == nil || err != nil { + return nil + } + + return versionConfig +} + +func kustomizeBuild( + k kustomize.Kustomize, + repoRoot string, + appPath string, + opts *v1alpha1.ApplicationSourceKustomize, + kustomizeOptions *v1alpha1.KustomizeOptions, + env *v1alpha1.Env, + buildOpts *kustomize.BuildOpts, + namespace string, +) ([]manifest, []kustomize.Image, []string, error) { + var targetObjs []*unstructured.Unstructured + + rawBytes, err := os.ReadFile(filepath.Join(appPath, "kustomization.yaml")) + if err != nil { + return nil, nil, nil, err + } + relPath, _ := filepath.Rel(repoRoot, appPath) + targetObjs, images, commands, err := k.Build(opts, kustomizeOptions, env, buildOpts, namespace) + if err != nil { + return nil, nil, nil, err + } + + jsonObjs, err := expandUnstructuredObjs(targetObjs) + if err != nil { + return nil, nil, nil, err + } + + manifests := make([]manifest, len(jsonObjs)) + for i, obj := range jsonObjs { + manifests[i] = manifest{ + rawManifest: rawBytes, + obj: obj, + path: relPath, + line: 0, + } + } + + return manifests, images, commands, nil +} diff --git a/reposerver/repository/repository.go b/reposerver/repository/repository.go index 286eb7eb0f215..af63584ccf097 100644 --- a/reposerver/repository/repository.go +++ b/reposerver/repository/repository.go @@ -43,6 +43,8 @@ import ( pluginclient "github.com/argoproj/argo-cd/v2/cmpserver/apiclient" "github.com/argoproj/argo-cd/v2/common" "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/pkg/codefresh" + "github.com/argoproj/argo-cd/v2/pkg/version_config_manager" "github.com/argoproj/argo-cd/v2/reposerver/apiclient" "github.com/argoproj/argo-cd/v2/reposerver/cache" "github.com/argoproj/argo-cd/v2/reposerver/metrics" @@ -96,6 +98,7 @@ type Service struct { newGitClient func(rawRepoURL string, root string, creds git.Creds, insecure bool, enableLfs bool, proxy string, noProxy string, opts ...git.ClientOpts) (git.Client, error) newHelmClient func(repoURL string, creds helm.Creds, enableOci bool, proxy string, noProxy string, opts ...helm.ClientOpts) helm.Client initConstants RepoServerInitConstants + versionConfigManager *version_config_manager.VersionConfigManager // now is usually just time.Now, but may be replaced by unit tests for testing purposes now func() time.Time } @@ -116,6 +119,9 @@ type RepoServerInitConstants struct { DisableHelmManifestMaxExtractedSize bool IncludeHiddenDirectories bool CMPUseManifestGeneratePaths bool + CodefreshApplicationVersioningEnabled bool + CodefreshUseApplicationConfiguration bool + CodefreshConfig codefresh.CodefreshConfig } // NewService returns a new instance of the Manifest service @@ -127,6 +133,11 @@ func NewService(metricsServer *metrics.MetricsServer, cache *cache.Cache, initCo repoLock := NewRepositoryLock() gitRandomizedPaths := io.NewRandomizedTempPaths(rootDir) helmRandomizedPaths := io.NewRandomizedTempPaths(rootDir) + + codefreshClient := codefresh.NewCodefreshClient(&initConstants.CodefreshConfig) + codefreshGraphQLRequests := codefresh.NewCodefreshGraphQLRequests(codefreshClient) + versionConfigManager := version_config_manager.NewVersionConfigManager(codefreshGraphQLRequests, cache) + return &Service{ parallelismLimitSemaphore: parallelismLimitSemaphore, repoLock: repoLock, @@ -137,13 +148,14 @@ func NewService(metricsServer *metrics.MetricsServer, cache *cache.Cache, initCo newHelmClient: func(repoURL string, creds helm.Creds, enableOci bool, proxy string, noProxy string, opts ...helm.ClientOpts) helm.Client { return helm.NewClientWithLock(repoURL, creds, sync.NewKeyLock(), enableOci, proxy, noProxy, opts...) }, - initConstants: initConstants, - now: time.Now, - gitCredsStore: gitCredsStore, - gitRepoPaths: gitRandomizedPaths, - chartPaths: helmRandomizedPaths, - gitRepoInitializer: directoryPermissionInitializer, - rootDir: rootDir, + initConstants: initConstants, + now: time.Now, + gitCredsStore: gitCredsStore, + gitRepoPaths: gitRandomizedPaths, + chartPaths: helmRandomizedPaths, + gitRepoInitializer: directoryPermissionInitializer, + rootDir: rootDir, + versionConfigManager: versionConfigManager, } } @@ -266,6 +278,13 @@ type operationSettings struct { allowConcurrent bool } +type manifest struct { + obj *unstructured.Unstructured + rawManifest []byte + path string + line int +} + // operationContext contains request values which are generated by runRepoOperation (on demand) by a call to the // provided operationContextSrc function. type operationContext struct { @@ -326,8 +345,26 @@ func (s *Service) runRepoOperation( return err } + cacheKey := revision + + if source.Kustomize != nil && len(source.Kustomize.Components) > 0 { + cacheKey, err = s.getCacheKeyWithKustomizeComponents( + revision, + repo, + source, + settings, + gitClient, + ) + if err != nil { + log.WithError(err). + WithField("repo", repo.Repo). + Warn("failed to calculate cache key with components, using only the revision of the base repository") + cacheKey = revision + } + } + if !settings.noCache { - if ok, err := cacheFn(revision, repoRefs, true); ok { + if ok, err := cacheFn(cacheKey, repoRefs, true); ok { return err } } @@ -427,7 +464,7 @@ func (s *Service) runRepoOperation( // Here commitSHA refers to the SHA of the actual commit, whereas revision refers to the branch/tag name etc // We use the commitSHA to generate manifests and store them in cache, and revision to retrieve them from cache - return operation(gitClient.Root(), commitSHA, revision, func() (*operationContext, error) { + return operation(gitClient.Root(), commitSHA, cacheKey, func() (*operationContext, error) { var signature string if verifyCommit { // When the revision is an annotated tag, we need to pass the unresolved revision (i.e. the tag name) @@ -550,7 +587,8 @@ func (s *Service) GenerateManifest(ctx context.Context, q *apiclient.ManifestReq return nil } - promise = s.runManifestGen(ctx, repoRoot, commitSHA, cacheKey, ctxSrc, q) + versionConfig := s.getVersionConfig(q.ApplicationMetadata) + promise = s.runManifestGen(ctx, repoRoot, commitSHA, cacheKey, ctxSrc, q, versionConfig) // The fist channel to send the message will resume this operation. // The main purpose for using channels here is to be able to unlock // the repository as soon as the lock in not required anymore. In @@ -619,13 +657,14 @@ func (s *Service) GenerateManifestWithFiles(stream apiclient.RepoServerService_G } } + versionConfig := s.getVersionConfig(req.ApplicationMetadata) promise := s.runManifestGen(stream.Context(), workDir, "streamed", metadata.Checksum, func() (*operationContext, error) { appPath, err := argopath.Path(workDir, req.ApplicationSource.Path) if err != nil { return nil, fmt.Errorf("failed to get app path: %w", err) } return &operationContext{appPath, ""}, nil - }, req) + }, req, versionConfig) var res *apiclient.ManifestResponse tarConcluded := false @@ -677,7 +716,7 @@ type generateManifestCh struct { // - or, the cache does contain a value for this key, but it is an expired manifest generation entry // - or, NoCache is true // Returns a ManifestResponse, or an error, but not both -func (s *Service) runManifestGen(ctx context.Context, repoRoot, commitSHA, cacheKey string, opContextSrc operationContextSrc, q *apiclient.ManifestRequest) *ManifestResponsePromise { +func (s *Service) runManifestGen(ctx context.Context, repoRoot, commitSHA, cacheKey string, opContextSrc operationContextSrc, q *apiclient.ManifestRequest, versionConfig *version_config_manager.VersionConfig) *ManifestResponsePromise { responseCh := make(chan *apiclient.ManifestResponse) tarDoneCh := make(chan bool) errCh := make(chan error) @@ -688,7 +727,7 @@ func (s *Service) runManifestGen(ctx context.Context, repoRoot, commitSHA, cache tarDoneCh: tarDoneCh, errCh: errCh, } - go s.runManifestGenAsync(ctx, repoRoot, commitSHA, cacheKey, opContextSrc, q, channels) + go s.runManifestGenAsync(ctx, repoRoot, commitSHA, cacheKey, opContextSrc, q, versionConfig, channels) return responsePromise } @@ -701,7 +740,7 @@ type repoRef struct { key string } -func (s *Service) runManifestGenAsync(ctx context.Context, repoRoot, commitSHA, cacheKey string, opContextSrc operationContextSrc, q *apiclient.ManifestRequest, ch *generateManifestCh) { +func (s *Service) runManifestGenAsync(ctx context.Context, repoRoot, commitSHA, cacheKey string, opContextSrc operationContextSrc, q *apiclient.ManifestRequest, versionConfig *version_config_manager.VersionConfig, ch *generateManifestCh) { defer func() { close(ch.errCh) close(ch.responseCh) @@ -713,6 +752,12 @@ func (s *Service) runManifestGenAsync(ctx context.Context, repoRoot, commitSHA, repoRefs := make(map[string]repoRef) var manifestGenResult *apiclient.ManifestResponse + + gitClient, err := s.newClient(q.Repo) + if err != nil { + log.Errorf("failed to build git client, application: %s: %s", q.AppName, err.Error()) + } + opContext, err := opContextSrc() if err == nil { // Much of the multi-source handling logic is duplicated in resolveReferencedSources. If making changes here, @@ -808,7 +853,12 @@ func (s *Service) runManifestGenAsync(ctx context.Context, repoRoot, commitSHA, } } - manifestGenResult, err = GenerateManifests(ctx, opContext.appPath, repoRoot, commitSHA, q, false, s.gitCredsStore, s.initConstants.MaxCombinedDirectoryManifestsSize, s.gitRepoPaths, WithCMPTarDoneChannel(ch.tarDoneCh), WithCMPTarExcludedGlobs(s.initConstants.CMPTarExcludedGlobs), WithCMPUseManifestGeneratePaths(s.initConstants.CMPUseManifestGeneratePaths)) + cfOptions := &CfOptions{ + ApplicationVersioningEnabled: s.initConstants.CodefreshApplicationVersioningEnabled, + VersionConfig: versionConfig, + GitClient: gitClient, + } + manifestGenResult, err = GenerateManifests(ctx, opContext.appPath, repoRoot, commitSHA, q, false, s.gitCredsStore, s.initConstants.MaxCombinedDirectoryManifestsSize, s.gitRepoPaths, cfOptions, WithCMPTarDoneChannel(ch.tarDoneCh), WithCMPTarExcludedGlobs(s.initConstants.CMPTarExcludedGlobs), WithCMPUseManifestGeneratePaths(s.initConstants.CMPUseManifestGeneratePaths)) } refSourceCommitSHAs := make(map[string]string) if len(repoRefs) > 0 { @@ -1105,7 +1155,7 @@ func isSourcePermitted(url string, repos []string) bool { return p.IsSourcePermitted(v1alpha1.ApplicationSource{RepoURL: url}) } -func helmTemplate(appPath string, repoRoot string, env *v1alpha1.Env, q *apiclient.ManifestRequest, isLocal bool, gitRepoPaths io.TempPaths) ([]*unstructured.Unstructured, string, error) { +func helmTemplate(appPath string, repoRoot string, env *v1alpha1.Env, q *apiclient.ManifestRequest, isLocal bool, gitRepoPaths io.TempPaths) ([]manifest, string, error) { concurrencyAllowed := helmConcurrencyDefault || isConcurrencyAllowed(appPath) if !concurrencyAllowed { manifestGenerateLock.Lock(appPath) @@ -1263,11 +1313,39 @@ func helmTemplate(appPath string, repoRoot string, env *v1alpha1.Env, q *apiclie return nil, "", err } } + + chartBytes := []byte{} + + // try to read Chart.yaml file + chartRelPath, err := filepath.Rel(repoRoot, filepath.Join(appPath, "Chart.yaml")) + if err == nil { + data, err := os.ReadFile(chartRelPath) + if err == nil { + chartBytes = data + } + } objs, err := kube.SplitYAML([]byte(out)) + if err != nil { + return nil, "", fmt.Errorf("failed to split helm resources: %w", err) + } + + jsonObjs, err := expandUnstructuredObjs(objs) + if err != nil { + return nil, "", err + } + manifests := make([]manifest, len(jsonObjs)) + for i, obj := range jsonObjs { + manifests[i] = manifest{ + rawManifest: chartBytes, + obj: obj, + path: chartRelPath, + line: 1, + } + } redactedCommand := redactPaths(command, gitRepoPaths, templateOpts.ExtraValues) - return objs, redactedCommand, err + return manifests, redactedCommand, err } // redactPaths removes temp repo paths, since those paths are randomized (and therefore not helpful for the user) and @@ -1424,9 +1502,13 @@ func WithCMPUseManifestGeneratePaths(enabled bool) 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, gitRepoPaths io.TempPaths, 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, cfOptions *CfOptions, opts ...GenerateManifestOpt) (*apiclient.ManifestResponse, error) { opt := newGenerateManifestOpt(opts...) - var targetObjs []*unstructured.Unstructured + + var ( + manifests []manifest + dest *v1alpha1.ApplicationDestination + ) resourceTracking := argo.NewResourceTracking() @@ -1446,7 +1528,7 @@ func GenerateManifests(ctx context.Context, appPath, repoRoot, revision string, switch appSourceType { case v1alpha1.ApplicationSourceTypeHelm: var command string - targetObjs, command, err = helmTemplate(appPath, repoRoot, env, q, isLocal, gitRepoPaths) + manifests, command, err = helmTemplate(appPath, repoRoot, env, q, isLocal, gitRepoPaths) commands = append(commands, command) case v1alpha1.ApplicationSourceTypeKustomize: kustomizeBinary := "" @@ -1454,17 +1536,18 @@ func GenerateManifests(ctx context.Context, appPath, repoRoot, revision string, kustomizeBinary = q.KustomizeOptions.BinaryPath } k := kustomize.NewKustomizeApp(repoRoot, appPath, q.Repo.GetGitCreds(gitCredsStore), repoURL, kustomizeBinary, q.Repo.Proxy, q.Repo.NoProxy) - targetObjs, _, commands, err = k.Build(q.ApplicationSource.Kustomize, q.KustomizeOptions, env, &kustomize.BuildOpts{ + manifests, _, commands, err = kustomizeBuild(k, repoRoot, appPath, q.ApplicationSource.Kustomize, q.KustomizeOptions, env, &kustomize.BuildOpts{ KubeVersion: text.SemVer(q.ApplicationSource.GetKubeVersionOrDefault(q.KubeVersion)), APIVersions: q.ApplicationSource.GetAPIVersionsOrDefault(q.ApiVersions), - }) + }, q.Namespace) case v1alpha1.ApplicationSourceTypePlugin: pluginName := "" if q.ApplicationSource.Plugin != nil { pluginName = q.ApplicationSource.Plugin.Name } + log.Infof("running plugin sidecar for app %s, revision %s", q.AppName, q.Revision) // if pluginName is provided it has to be `-` or just `` if plugin version is empty - targetObjs, err = runConfigManagementPluginSidecars(ctx, appPath, repoRoot, pluginName, env, q, q.Repo.GetGitCreds(gitCredsStore), opt.cmpTarDoneCh, opt.cmpTarExcludedGlobs, opt.cmpUseManifestGeneratePaths) + manifests, err = runConfigManagementPluginSidecars(ctx, appPath, repoRoot, pluginName, env, q, q.Repo.GetGitCreds(gitCredsStore), opt.cmpTarDoneCh, opt.cmpTarExcludedGlobs, opt.cmpUseManifestGeneratePaths) if err != nil { err = fmt.Errorf("plugin sidecar failed. %s", err.Error()) } @@ -1474,57 +1557,84 @@ func GenerateManifests(ctx context.Context, appPath, repoRoot, revision string, directory = &v1alpha1.ApplicationSourceDirectory{} } logCtx := log.WithField("application", q.AppName) - targetObjs, err = findManifests(logCtx, appPath, repoRoot, env, *directory, q.EnabledSourceTypes, maxCombinedManifestQuantity) + manifests, err = findManifests(logCtx, appPath, repoRoot, env, *directory, q.EnabledSourceTypes, maxCombinedManifestQuantity) } if err != nil { return nil, err } - manifests := make([]string, 0) - for _, obj := range targetObjs { - if obj == nil { - continue - } - - var targets []*unstructured.Unstructured - if obj.IsList() { - err = obj.EachListItem(func(object runtime.Object) error { - unstructuredObj, ok := object.(*unstructured.Unstructured) - if ok { - targets = append(targets, unstructuredObj) - return nil - } - return fmt.Errorf("resource list item has unexpected type") - }) + resManifests := make([]*apiclient.Manifest, 0) + for _, m := range manifests { + if q.AppLabelKey != "" && q.AppName != "" && !kube.IsCRD(m.obj) { + err = resourceTracking.SetAppInstance(m.obj, q.AppLabelKey, q.AppName, q.Namespace, v1alpha1.TrackingMethod(q.TrackingMethod), q.InstallationID) if err != nil { return nil, err } - } else if isNullList(obj) { - // noop - } else { - targets = []*unstructured.Unstructured{obj} } - for _, target := range targets { - if q.AppLabelKey != "" && q.AppName != "" && !kube.IsCRD(target) { - err = resourceTracking.SetAppInstance(target, q.AppLabelKey, q.AppName, q.Namespace, v1alpha1.TrackingMethod(q.TrackingMethod), q.InstallationID) - if err != nil { - return nil, fmt.Errorf("failed to set app instance tracking info on manifest: %w", err) - } - } - manifestStr, err := json.Marshal(target.Object) - if err != nil { - return nil, err - } - manifests = append(manifests, string(manifestStr)) + manifestStr, err := json.Marshal(m.obj) + if err != nil { + return nil, err } + + resManifests = append(resManifests, &apiclient.Manifest{ + CompiledManifest: string(manifestStr), + RawManifest: string(m.rawManifest), + Path: m.path, + Line: int32(m.line), + }) } - return &apiclient.ManifestResponse{ - Manifests: manifests, + res := apiclient.ManifestResponse{ + Manifests: resManifests, SourceType: string(appSourceType), Commands: commands, - }, nil + } + + if appSourceType == v1alpha1.ApplicationSourceTypeHelm { + if cfOptions != nil && cfOptions.ApplicationVersioningEnabled { + appVersions, err := getAppVersions(appPath, cfOptions.VersionConfig) + if err != nil { + errorMessage := fmt.Sprintf("failed to retrieve application version, app name: %q: %s", q.AppName, err.Error()) + if (cfOptions.VersionConfig.ResourceName == version_config_manager.DefaultVersionSource) && + (err.Error() == "unknown key appVersion") { + log.Info(errorMessage) + } else { + log.Error(errorMessage) + } + } else { + res.ApplicationVersions = &apiclient.ApplicationVersions{ + AppVersion: appVersions.AppVersion, + Dependencies: &apiclient.Dependencies{ + Lock: appVersions.Dependencies.Lock, + Deps: appVersions.Dependencies.Deps, + Requirements: appVersions.Dependencies.Requirements, + }, + } + } + } else { + log.Infof("Application versioning disabled by flag (CODEFRESH_APPLICATION_VERSIONING_ENABLED)") + } + } + + if cfOptions != nil && cfOptions.GitClient != nil { + m, err := cfOptions.GitClient.RevisionMetadata(revision) + if err != nil { + log.Errorf("failed to retrieve git information, app name: %q: %s", q.AppName, err.Error()) + } else { + log.Infof("successful to retrieve git information, app name: %q, author: %q, message: %q", q.AppName, m.Author, m.Date) + res.CommitMessage = m.Message + res.CommitAuthor = m.Author + res.CommitDate = &metav1.Time{Time: m.Date} + } + } else { + log.Warnf("failed to retrieve git information, app name: %q, because git client is nil", q.AppName) + } + if dest != nil { + res.Namespace = dest.Namespace + res.Server = dest.Server + } + return &res, nil } func newEnv(q *apiclient.ManifestRequest, revision string) *v1alpha1.Env { @@ -1665,7 +1775,7 @@ func isNullList(obj *unstructured.Unstructured) bool { var manifestFile = regexp.MustCompile(`^.*\.(yaml|yml|json|jsonnet)$`) // findManifests looks at all yaml files in a directory and unmarshals them into a list of unstructured objects -func findManifests(logCtx *log.Entry, appPath string, repoRoot string, env *v1alpha1.Env, directory v1alpha1.ApplicationSourceDirectory, enabledManifestGeneration map[string]bool, maxCombinedManifestQuantity resource.Quantity) ([]*unstructured.Unstructured, error) { +func findManifests(logCtx *log.Entry, appPath string, repoRoot string, env *v1alpha1.Env, directory v1alpha1.ApplicationSourceDirectory, enabledManifestGeneration map[string]bool, maxCombinedManifestQuantity resource.Quantity) ([]manifest, error) { // Validate the directory before loading any manifests to save memory. potentiallyValidManifests, err := getPotentiallyValidManifests(logCtx, appPath, repoRoot, directory.Recurse, directory.Include, directory.Exclude, maxCombinedManifestQuantity) if err != nil { @@ -1673,12 +1783,21 @@ func findManifests(logCtx *log.Entry, appPath string, repoRoot string, env *v1al return nil, fmt.Errorf("failed to get potentially valid manifests: %w", err) } - var objs []*unstructured.Unstructured + absRepoRoot, err := filepath.Abs(repoRoot) + if err != nil { + return nil, err + } + var manifests []manifest for _, potentiallyValidManifest := range potentiallyValidManifests { manifestPath := potentiallyValidManifest.path manifestFileInfo := potentiallyValidManifest.fileInfo + absPath, _ := filepath.Abs(manifestPath) + + repoRelPath, _ := filepath.Rel(absRepoRoot, absPath) + if strings.HasSuffix(manifestFileInfo.Name(), ".jsonnet") { + var objs []*unstructured.Unstructured if !discovery.IsManifestGenerationEnabled(v1alpha1.ApplicationSourceTypeDirectory, enabledManifestGeneration) { continue } @@ -1686,6 +1805,10 @@ func findManifests(logCtx *log.Entry, appPath string, repoRoot string, env *v1al if err != nil { return nil, err } + rawBytes, err := os.ReadFile(manifestPath) + if err != nil { + return nil, err + } jsonStr, err := vm.EvaluateFile(manifestPath) if err != nil { return nil, status.Errorf(codes.FailedPrecondition, "Failed to evaluate jsonnet %q: %v", manifestFileInfo.Name(), err) @@ -1704,14 +1827,39 @@ func findManifests(logCtx *log.Entry, appPath string, repoRoot string, env *v1al } objs = append(objs, &jsonObj) } + + for _, obj := range objs { + manifests = append(manifests, manifest{ + rawManifest: rawBytes, + obj: obj, + path: repoRelPath, + line: 1, // TODO: can add later + }) + } } else { + var objs []*unstructured.Unstructured err := getObjsFromYAMLOrJson(logCtx, manifestPath, manifestFileInfo.Name(), &objs) if err != nil { return nil, err } + + rawBytes, err := os.ReadFile(manifestPath) + if err != nil { + return nil, err + } + + for _, obj := range objs { + manifests = append(manifests, manifest{ + rawManifest: rawBytes, + obj: obj, + path: repoRelPath, + line: 1, // TODO: can add later + }) + } } } - return objs, nil + + return manifests, nil } // getObjsFromYAMLOrJson unmarshals the given yaml or json file and appends it to the given list of objects. @@ -1903,6 +2051,31 @@ func getPotentiallyValidManifests(logCtx *log.Entry, appPath string, repoRoot st return potentiallyValidManifests, nil } +func expandUnstructuredObjs(objs []*unstructured.Unstructured) ([]*unstructured.Unstructured, error) { + ret := make([]*unstructured.Unstructured, 0, len(objs)) + for _, obj := range objs { + if obj.IsList() { + err := obj.EachListItem(func(object runtime.Object) error { + unstructuredObj, ok := object.(*unstructured.Unstructured) + if ok { + ret = append(ret, unstructuredObj) + return nil + } + return fmt.Errorf("resource list item has unexpected type") + }) + if err != nil { + return nil, err + } + } else if isNullList(obj) { + // noop + } else { + ret = append(ret, obj) + } + } + + return ret, nil +} + func makeJsonnetVm(appPath string, repoRoot string, sourceJsonnet v1alpha1.ApplicationSourceJsonnet, env *v1alpha1.Env) (*jsonnet.VM, error) { vm := jsonnet.MakeVM() for i, j := range sourceJsonnet.TLAs { @@ -1981,7 +2154,7 @@ func getPluginParamEnvs(envVars []string, plugin *v1alpha1.ApplicationSourcePlug return env, nil } -func runConfigManagementPluginSidecars(ctx context.Context, appPath, repoPath, pluginName string, envVars *v1alpha1.Env, q *apiclient.ManifestRequest, creds git.Creds, tarDoneCh chan<- bool, tarExcludedGlobs []string, useManifestGeneratePaths bool) ([]*unstructured.Unstructured, error) { +func runConfigManagementPluginSidecars(ctx context.Context, appPath, repoPath, pluginName string, envVars *v1alpha1.Env, q *apiclient.ManifestRequest, creds git.Creds, tarDoneCh chan<- bool, tarExcludedGlobs []string, useManifestGeneratePaths bool) ([]manifest, error) { // compute variables. env, err := getPluginEnvs(envVars, q) if err != nil { @@ -2023,7 +2196,7 @@ func runConfigManagementPluginSidecars(ctx context.Context, appPath, repoPath, p if err != nil { return nil, fmt.Errorf("error generating manifests in cmp: %w", err) } - var manifests []*unstructured.Unstructured + manifests := []manifest{} for _, manifestString := range cmpManifests.Manifests { manifestObjs, err := kube.SplitYAML([]byte(manifestString)) if err != nil { @@ -2034,7 +2207,20 @@ func runConfigManagementPluginSidecars(ctx context.Context, appPath, repoPath, p log.Debugf("Failed to convert generated manifests. Beginning of generated manifests: %q", sanitizedManifestString) return nil, fmt.Errorf("failed to convert CMP manifests to unstructured objects: %s", err.Error()) } - manifests = append(manifests, manifestObjs...) + + jsonObjs, err := expandUnstructuredObjs(manifestObjs) + if err != nil { + return nil, err + } + + for _, obj := range jsonObjs { + manifests = append(manifests, manifest{ + rawManifest: []byte(""), + obj: obj, + path: "unknown", + line: 1, + }) + } } return manifests, nil } @@ -2234,7 +2420,7 @@ func populateKustomizeAppDetails(res *apiclient.RepoAppDetailsResponse, q *apicl ApplicationSource: q.Source, } env := newEnv(&fakeManifestRequest, reversion) - _, images, _, err := k.Build(q.Source.Kustomize, q.KustomizeOptions, env, nil) + _, images, _, err := k.Build(q.Source.Kustomize, q.KustomizeOptions, env, nil, "") if err != nil { return err } @@ -2930,7 +3116,7 @@ func (s *Service) UpdateRevisionForPaths(_ context.Context, request *apiclient.U }, nil } - logCtx.Debugf("changes found for application %s in repo %s from revision %s to revision %s", request.AppName, repo.Repo, syncedRevision, revision) + logCtx.Debugf("changes not found for application %s in repo %s from revision %s to revision %s", request.AppName, repo.Repo, syncedRevision, revision) return &apiclient.UpdateRevisionForPathsResponse{ Revision: revision, Changes: true, @@ -2964,3 +3150,57 @@ func (s *Service) updateCachedRevision(logCtx *log.Entry, oldRev string, newRev logCtx.Debugf("manifest cache updated for application %s in repo %s from revision %s to revision %s", request.AppName, request.GetRepo().Repo, oldRev, newRev) return nil } + +func (s *Service) GetChangeRevision(ctx context.Context, request *apiclient.ChangeRevisionRequest) (*apiclient.ChangeRevisionResponse, error) { + logCtx := log.WithFields(log.Fields{"application": request.AppName, "appNamespace": request.Namespace}) + + repo := request.GetRepo() + currentRevision := request.GetCurrentRevision() + previousRevision := request.GetPreviousRevision() + refreshPaths := request.GetPaths() + + if repo == nil { + return nil, status.Error(codes.InvalidArgument, "must pass a valid repo") + } + + if len(refreshPaths) == 0 { + return nil, status.Error(codes.InvalidArgument, "must pass a refresh path") + } + + gitClientOpts := git.WithCache(s.cache, true) + gitClient, revision, err := s.newClientResolveRevision(repo, currentRevision, gitClientOpts) + if err != nil { + return nil, status.Errorf(codes.Internal, "unable to resolve git revision %s: %v", revision, err) + } + + s.metricsServer.IncPendingRepoRequest(repo.Repo) + defer s.metricsServer.DecPendingRepoRequest(repo.Repo) + + closer, err := s.repoLock.Lock(gitClient.Root(), revision, true, func() (goio.Closer, error) { + return s.checkoutRevision(gitClient, revision, false) + }) + if err != nil { + return nil, status.Errorf(codes.Internal, "unable to checkout git repo %s with revision %s: %v", repo.Repo, revision, err) + } + defer io.Close(closer) + revisions, err := gitClient.ListRevisions(previousRevision, revision) + if err != nil { + return nil, status.Errorf(codes.Internal, "failed to get revisions %s..%s", previousRevision, revision) + } + for _, rev := range revisions { + files, err := gitClient.DiffTree(rev) + if err != nil { + continue + } + changedFiles := apppathutil.AppFilesHaveChanged(refreshPaths, files) + if changedFiles { + logCtx.Debugf("changes found for application %s in repo %s from revision %s to revision %s", request.AppName, repo.Repo, previousRevision, revision) + return &apiclient.ChangeRevisionResponse{ + Revision: rev, + }, nil + } + } + + logCtx.Debugf("changes not found for application %s in repo %s from revision %s to revision %s", request.AppName, repo.Repo, previousRevision, revision) + return &apiclient.ChangeRevisionResponse{}, nil +} diff --git a/reposerver/repository/repository.proto b/reposerver/repository/repository.proto index 784ef0cafa12b..5e9fe585dba50 100644 --- a/reposerver/repository/repository.proto +++ b/reposerver/repository/repository.proto @@ -3,6 +3,8 @@ option go_package = "github.com/argoproj/argo-cd/v2/reposerver/apiclient"; package repository; +import "k8s.io/api/core/v1/generated.proto"; +import "k8s.io/apimachinery/pkg/apis/meta/v1/generated.proto"; import "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1/generated.proto"; import "google/protobuf/empty.proto"; @@ -42,6 +44,7 @@ message ManifestRequest { string annotationManifestGeneratePaths = 26; // Holds instance installation id string installationID = 27; + k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta applicationMetadata = 28; } message ManifestRequestWithFiles { @@ -89,8 +92,36 @@ message ResolveRevisionResponse { string ambiguousRevision = 2; } +message Manifest { + // The processed manifest that needs to be applied to the cluster + string compiledManifest = 1; + // The pre-processed manifest (for example the kustomization.yaml + // when using kustmize or the values.yaml when using helm). + string rawManifest = 2; + // The path of the raw manifest inside the repo + string path = 3; + // The line in the file where the object starts + int32 line = 4; +} + +message Dependencies { + // Content of Chart.lock + string lock = 1; + // Content of Cart.yaml/dependencies + string deps = 2; + // Content of requirements.yaml + string requirements = 3; +} + +message ApplicationVersions { + // Application version presented by single value + string appVersion = 1; + // Yaml content of dependencies + Dependencies dependencies = 2; +} + message ManifestResponse { - repeated string manifests = 1; + repeated Manifest manifests = 1; string namespace = 2; string server = 3; // resolved revision @@ -98,8 +129,15 @@ message ManifestResponse { string sourceType = 6; // Raw response of git verify-commit operation (always the empty string for Helm) string verifyResult = 7; + string commitMessage = 8; + string commitAuthor = 9; + k8s.io.apimachinery.pkg.apis.meta.v1.Time commitDate = 10; + // A version of the application and its dependencies + ApplicationVersions applicationVersions = 11; + // for multisourced apps will be [0,12,20], so this means that 0-11 - from first app source, 12-19 from second one, 20-x - third one + repeated int32 sourcesManifestsStartingIdx = 12; // Commands is the list of commands used to hydrate the manifests - repeated string commands = 8; + repeated string commands = 13; } message ListRefsRequest { @@ -296,6 +334,19 @@ message UpdateRevisionForPathsResponse { string revision = 2; } +message ChangeRevisionRequest { + string appName = 1; + string namespace = 2; + string currentRevision = 3; + string previousRevision = 4; + repeated string paths = 5; + github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.Repository repo = 6; +} + +message ChangeRevisionResponse { + string revision = 1; +} + // ManifestService service RepoServerService { @@ -334,7 +385,7 @@ service RepoServerService { // Get the meta-data (author, date, tags, message) for a specific revision of the repo rpc GetRevisionMetadata(RepoServerRevisionMetadataRequest) returns (github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.RevisionMetadata) { } - + // Get the chart details (author, date, tags, message) for a specific revision of the repo rpc GetRevisionChartDetails(RepoServerRevisionChartDetailsRequest) returns (github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ChartDetails) { } @@ -354,4 +405,7 @@ service RepoServerService { // UpdateRevisionForPaths will compare two revisions and update the cache with the new revision if no changes are detected in the provided paths rpc UpdateRevisionForPaths(UpdateRevisionForPathsRequest) returns (UpdateRevisionForPathsResponse) { } + + rpc GetChangeRevision(ChangeRevisionRequest) returns (ChangeRevisionResponse) { + } } diff --git a/reposerver/repository/repository_test.go b/reposerver/repository/repository_test.go index ea10c92ad9183..b8db7e0ce2ca4 100644 --- a/reposerver/repository/repository_test.go +++ b/reposerver/repository/repository_test.go @@ -94,11 +94,15 @@ func newCacheMocksWithOpts(repoCacheExpiration, revisionCacheExpiration, revisio cacheutilCache := cacheutil.NewCache(mockRepoCache.RedisClient) return &repoCacheMocks{ cacheutilCache: cacheutilCache, - cache: cache.NewCache(cacheutilCache, repoCacheExpiration, revisionCacheExpiration, revisionCacheLockTimeout), + cache: cache.NewCache(cacheutilCache, repoCacheExpiration, revisionCacheExpiration, revisionCacheLockTimeout, 1*time.Minute), mockCache: mockRepoCache, } } +func applyCfGitClientMocks(gitClientMock *gitmocks.Client) { + gitClientMock.On("RevisionMetadata", mock.Anything).Return(nil, errors.New("cant fetch metadata")) +} + func newServiceWithMocks(t *testing.T, root string, signed bool) (*Service, *gitmocks.Client, *repoCacheMocks) { t.Helper() root, err := filepath.Abs(root) @@ -165,13 +169,15 @@ func newServiceWithOpt(t *testing.T, cf clientFunc, root string) (*Service, *git func newService(t *testing.T, root string) *Service { t.Helper() - service, _, _ := newServiceWithMocks(t, root, false) + service, gm, _ := newServiceWithMocks(t, root, false) + applyCfGitClientMocks(gm) return service } func newServiceWithSignature(t *testing.T, root string) *Service { t.Helper() - service, _, _ := newServiceWithMocks(t, root, true) + service, gm, _ := newServiceWithMocks(t, root, true) + applyCfGitClientMocks(gm) return service } @@ -192,6 +198,12 @@ func newServiceWithCommitSHA(t *testing.T, root, revision string) *Service { gitClient.On("LsRemote", revision).Return(revision, revisionErr) gitClient.On("CommitSHA").Return("632039659e542ed7de0c170a4fcc1c571b288fc0", nil) gitClient.On("Root").Return(root) + gitClient.On("RevisionMetadata", mock.Anything).Return(&git.RevisionMetadata{ + Message: "test", + Author: "author", + Date: time.Now(), + Tags: []string{"tag1", "tag2"}, + }, nil) paths.On("GetPath", mock.Anything).Return(root, nil) paths.On("GetPathIfExists", mock.Anything).Return(root, nil) }, root) @@ -223,7 +235,7 @@ func TestGenerateYamlManifestInDir(t *testing.T) { assert.Len(t, res1.Manifests, countOfManifests) // 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"), nil) + res2, err := GenerateManifests(context.Background(), "./testdata/concatenated", "/", "", &q, false, &git.NoopCredsStore{}, resource.MustParse("0"), nil, nil) require.NoError(t, err) assert.Len(t, res2.Manifests, 3) } @@ -282,7 +294,7 @@ func Test_GenerateManifests_NoOutOfBoundsAccess(t *testing.T) { Repo: &argoappv1.Repository{}, ApplicationSource: &argoappv1.ApplicationSource{}, ProjectName: "something", ProjectSourceRepos: []string{"*"}, } - res, err := GenerateManifests(context.Background(), repoDir, "", "", &q, false, &git.NoopCredsStore{}, resource.MustParse("0"), nil) + res, err := GenerateManifests(context.Background(), repoDir, "", "", &q, false, &git.NoopCredsStore{}, resource.MustParse("0"), nil, nil) require.Error(t, err) assert.NotContains(t, err.Error(), mustNotContain) require.ErrorContains(t, err, "illegal filepath") @@ -300,7 +312,7 @@ func TestGenerateManifests_MissingSymlinkDestination(t *testing.T) { Repo: &argoappv1.Repository{}, ApplicationSource: &argoappv1.ApplicationSource{}, ProjectName: "something", ProjectSourceRepos: []string{"*"}, } - _, err = GenerateManifests(context.Background(), repoDir, "", "", &q, false, &git.NoopCredsStore{}, resource.MustParse("0"), nil) + _, err = GenerateManifests(context.Background(), repoDir, "", "", &q, false, &git.NoopCredsStore{}, resource.MustParse("0"), nil, nil) require.NoError(t, err) } @@ -316,7 +328,7 @@ func TestGenerateManifests_K8SAPIResetCache(t *testing.T) { ProjectSourceRepos: []string{"*"}, } - cachedFakeResponse := &apiclient.ManifestResponse{Manifests: []string{"Fake"}, Revision: mock.Anything} + cachedFakeResponse := &apiclient.ManifestResponse{Manifests: []*apiclient.Manifest{{CompiledManifest: "Fake"}}, Revision: mock.Anything} err := service.cache.SetManifests(mock.Anything, &src, q.RefSources, &q, "", "", "", "", &cache.CachedManifestResponse{ManifestResponse: cachedFakeResponse}, nil, "") require.NoError(t, err) @@ -334,6 +346,7 @@ func TestGenerateManifests_K8SAPIResetCache(t *testing.T) { func TestGenerateManifests_EmptyCache(t *testing.T) { service, gitMocks, mockCache := newServiceWithMocks(t, "../../manifests/base", false) + applyCfGitClientMocks(gitMocks) src := argoappv1.ApplicationSource{Path: "."} q := apiclient.ManifestRequest{ @@ -488,6 +501,7 @@ func TestGenerateManifestsHelmWithRefs_CachedNoLsRemote(t *testing.T) { func TestHelmManifestFromChartRepo(t *testing.T) { root := t.TempDir() service, gitMocks, mockCache := newServiceWithMocks(t, root, false) + applyCfGitClientMocks(gitMocks) source := &argoappv1.ApplicationSource{Chart: "my-chart", TargetRevision: ">= 1.0.0"} request := &apiclient.ManifestRequest{ Repo: &argoappv1.Repository{}, ApplicationSource: source, NoCache: true, ProjectName: "something", @@ -497,7 +511,13 @@ func TestHelmManifestFromChartRepo(t *testing.T) { require.NoError(t, err) assert.NotNil(t, response) assert.Equal(t, &apiclient.ManifestResponse{ - Manifests: []string{"{\"apiVersion\":\"v1\",\"kind\":\"ConfigMap\",\"metadata\":{\"name\":\"my-map\"}}"}, + Manifests: []*apiclient.Manifest{ + { + CompiledManifest: "{\"apiVersion\":\"v1\",\"kind\":\"ConfigMap\",\"metadata\":{\"name\":\"my-map\"}}", + Path: "Chart.yaml", + Line: 1, + }, + }, Namespace: "", Server: "", Revision: "1.1.0", @@ -535,7 +555,13 @@ func TestHelmChartReferencingExternalValues(t *testing.T) { require.NoError(t, err) assert.NotNil(t, response) assert.Equal(t, &apiclient.ManifestResponse{ - Manifests: []string{"{\"apiVersion\":\"v1\",\"kind\":\"ConfigMap\",\"metadata\":{\"name\":\"my-map\"}}"}, + Manifests: []*apiclient.Manifest{ + { + CompiledManifest: "{\"apiVersion\":\"v1\",\"kind\":\"ConfigMap\",\"metadata\":{\"name\":\"my-map\"}}", + Path: "Chart.yaml", + Line: 1, + }, + }, Namespace: "", Server: "", Revision: "1.1.0", @@ -643,6 +669,7 @@ func TestHelmChartReferencingExternalValues_OutOfBounds_Symlink(t *testing.T) { func TestGenerateManifestsUseExactRevision(t *testing.T) { service, gitClient, _ := newServiceWithMocks(t, ".", false) + applyCfGitClientMocks(gitClient) src := argoappv1.ApplicationSource{Path: "./testdata/recurse", Directory: &argoappv1.ApplicationSourceDirectory{Recurse: true}} @@ -653,7 +680,7 @@ func TestGenerateManifestsUseExactRevision(t *testing.T) { res1, err := service.GenerateManifest(context.Background(), &q) require.NoError(t, err) - assert.Len(t, res1.Manifests, 2) + assert.Len(t, res1.Manifests, 4) assert.Equal(t, "abc", gitClient.Calls[0].Arguments[0]) } @@ -669,7 +696,7 @@ func TestRecurseManifestsInDir(t *testing.T) { res1, err := service.GenerateManifest(context.Background(), &q) require.NoError(t, err) - assert.Len(t, res1.Manifests, 2) + assert.Len(t, res1.Manifests, 4) } func TestInvalidManifestsInDir(t *testing.T) { @@ -701,7 +728,7 @@ func TestNilMetadataAccessors(t *testing.T) { res, err := service.GenerateManifest(context.Background(), &q) require.NoError(t, err) assert.Len(t, res.Manifests, 1) - assert.Equal(t, expected, res.Manifests[0]) + assert.Equal(t, expected, res.Manifests[0].CompiledManifest) } func TestGenerateJsonnetManifestInDir(t *testing.T) { @@ -724,7 +751,7 @@ func TestGenerateJsonnetManifestInDir(t *testing.T) { } res1, err := service.GenerateManifest(context.Background(), &q) require.NoError(t, err) - assert.Len(t, res1.Manifests, 2) + assert.Len(t, res1.Manifests, 3) } func TestGenerateJsonnetManifestInRootDir(t *testing.T) { @@ -747,7 +774,7 @@ func TestGenerateJsonnetManifestInRootDir(t *testing.T) { } res1, err := service.GenerateManifest(context.Background(), &q) require.NoError(t, err) - assert.Len(t, res1.Manifests, 2) + assert.Len(t, res1.Manifests, 3) } func TestGenerateJsonnetLibOutside(t *testing.T) { @@ -1111,7 +1138,7 @@ func TestGenerateHelmWithValues(t *testing.T) { replicasVerified := false for _, src := range res.Manifests { obj := unstructured.Unstructured{} - err = json.Unmarshal([]byte(src), &obj) + err = json.Unmarshal([]byte(src.CompiledManifest), &obj) require.NoError(t, err) if obj.GetKind() == "Deployment" && obj.GetName() == "test-redis-slave" { @@ -1173,7 +1200,7 @@ func TestGenerateHelmWithEnvVars(t *testing.T) { replicasVerified := false for _, src := range res.Manifests { obj := unstructured.Unstructured{} - err = json.Unmarshal([]byte(src), &obj) + err = json.Unmarshal([]byte(src.CompiledManifest), &obj) require.NoError(t, err) if obj.GetKind() == "Deployment" && obj.GetName() == "production-redis-slave" { @@ -1250,7 +1277,13 @@ func TestHelmManifestFromChartRepoWithValueFile(t *testing.T) { require.NoError(t, err) assert.NotNil(t, response) assert.Equal(t, &apiclient.ManifestResponse{ - Manifests: []string{"{\"apiVersion\":\"v1\",\"kind\":\"ConfigMap\",\"metadata\":{\"name\":\"my-map\"}}"}, + Manifests: []*apiclient.Manifest{ + { + CompiledManifest: "{\"apiVersion\":\"v1\",\"kind\":\"ConfigMap\",\"metadata\":{\"name\":\"my-map\"}}", + Path: "Chart.yaml", + Line: 1, + }, + }, Namespace: "", Server: "", Revision: "1.1.0", @@ -1490,7 +1523,7 @@ func TestGenerateHelmWithFileParameter(t *testing.T) { ProjectSourceRepos: []string{"*"}, }) require.NoError(t, err) - assert.Contains(t, res.Manifests[6], `"replicas":2`, "ValuesObject should override Values") + assert.Contains(t, res.Manifests[6].CompiledManifest, `"replicas":2`, "ValuesObject should override Values") } func TestGenerateNullList(t *testing.T) { @@ -1505,8 +1538,8 @@ func TestGenerateNullList(t *testing.T) { ProjectSourceRepos: []string{"*"}, }) require.NoError(t, err) - assert.Len(t, res1.Manifests, 1) - assert.Contains(t, res1.Manifests[0], "prometheus-operator-operator") + assert.Len(t, res1.Manifests, 2) + assert.Contains(t, res1.Manifests[1].CompiledManifest, "prometheus-operator-operator") }) t.Run("empty list", func(t *testing.T) { @@ -1518,8 +1551,8 @@ func TestGenerateNullList(t *testing.T) { ProjectSourceRepos: []string{"*"}, }) require.NoError(t, err) - assert.Len(t, res1.Manifests, 1) - assert.Contains(t, res1.Manifests[0], "prometheus-operator-operator") + assert.Len(t, res1.Manifests, 2) + assert.Contains(t, res1.Manifests[1].CompiledManifest, "prometheus-operator-operator") }) t.Run("weird list", func(t *testing.T) { @@ -1556,7 +1589,7 @@ func TestGenerateFromUTF16(t *testing.T) { ProjectName: "something", ProjectSourceRepos: []string{"*"}, } - res1, err := GenerateManifests(context.Background(), "./testdata/utf-16", "/", "", &q, false, &git.NoopCredsStore{}, resource.MustParse("0"), nil) + res1, err := GenerateManifests(context.Background(), "./testdata/utf-16", "/", "", &q, false, &git.NoopCredsStore{}, resource.MustParse("0"), nil, nil) require.NoError(t, err) assert.Len(t, res1.Manifests, 2) } @@ -1978,7 +2011,7 @@ func TestGenerateManifestsWithAppParameterFile(t *testing.T) { resourceByKindName := make(map[string]*unstructured.Unstructured) for _, manifest := range manifests.Manifests { var un unstructured.Unstructured - err := yaml.Unmarshal([]byte(manifest), &un) + err := yaml.Unmarshal([]byte(manifest.CompiledManifest), &un) require.NoError(t, err) resourceByKindName[fmt.Sprintf("%s/%s", un.GetKind(), un.GetName())] = &un } @@ -2008,7 +2041,7 @@ func TestGenerateManifestsWithAppParameterFile(t *testing.T) { resourceByKindName := make(map[string]*unstructured.Unstructured) for _, manifest := range manifests.Manifests { var un unstructured.Unstructured - err := yaml.Unmarshal([]byte(manifest), &un) + err := yaml.Unmarshal([]byte(manifest.CompiledManifest), &un) require.NoError(t, err) resourceByKindName[fmt.Sprintf("%s/%s", un.GetKind(), un.GetName())] = &un } @@ -2039,7 +2072,7 @@ func TestGenerateManifestsWithAppParameterFile(t *testing.T) { resourceByKindName := make(map[string]*unstructured.Unstructured) for _, manifest := range manifests.Manifests { var un unstructured.Unstructured - err := yaml.Unmarshal([]byte(manifest), &un) + err := yaml.Unmarshal([]byte(manifest.CompiledManifest), &un) require.NoError(t, err) resourceByKindName[fmt.Sprintf("%s/%s", un.GetKind(), un.GetName())] = &un } @@ -2092,7 +2125,7 @@ func TestGenerateManifestsWithAppParameterFile(t *testing.T) { resourceByKindName := make(map[string]*unstructured.Unstructured) for _, manifest := range manifests.Manifests { var un unstructured.Unstructured - err := yaml.Unmarshal([]byte(manifest), &un) + err := yaml.Unmarshal([]byte(manifest.CompiledManifest), &un) require.NoError(t, err) resourceByKindName[fmt.Sprintf("%s/%s", un.GetKind(), un.GetName())] = &un } @@ -2303,9 +2336,15 @@ func TestGenerateMultiSourceHelmWithFileParameter(t *testing.T) { if !tc.expectedErr { require.NoError(t, err) + manifests := []apiclient.Manifest{} + + for _, i := range res.Manifests { + manifests = append(manifests, *i) + } + // Check that any of the manifests contains the secret - idx := slices.IndexFunc(res.Manifests, func(content string) bool { - return strings.Contains(content, tc.expectedContent) + idx := slices.IndexFunc(manifests, func(content apiclient.Manifest) bool { + return strings.Contains(content.CompiledManifest, tc.expectedContent) }) assert.GreaterOrEqual(t, idx, 0, "No manifest contains the value set with the helm fileParameters") } else { @@ -2357,7 +2396,7 @@ func TestFindResources(t *testing.T) { require.NoError(t, err) var names []string for i := range objs { - names = append(names, objs[i].GetName()) + names = append(names, objs[i].obj.GetName()) } assert.ElementsMatch(t, tc.expectedNames, names) }) @@ -2373,7 +2412,7 @@ func TestFindManifests_Exclude(t *testing.T) { require.NoError(t, err) require.Len(t, objs, 1) - assert.Equal(t, "nginx-deployment", objs[0].GetName()) + assert.Equal(t, "nginx-deployment", objs[0].obj.GetName()) } func TestFindManifests_Exclude_NothingMatches(t *testing.T) { @@ -2386,7 +2425,7 @@ func TestFindManifests_Exclude_NothingMatches(t *testing.T) { require.Len(t, objs, 2) assert.ElementsMatch(t, - []string{"nginx-deployment", "nginx-deployment-sub"}, []string{objs[0].GetName(), objs[1].GetName()}) + []string{"nginx-deployment", "nginx-deployment-sub"}, []string{objs[0].obj.GetName(), objs[1].obj.GetName()}) } func tempDir(t *testing.T) string { diff --git a/reposerver/repository/testdata/symlinks/bam b/reposerver/repository/testdata/symlinks/bam new file mode 120000 index 0000000000000..3f95386662513 --- /dev/null +++ b/reposerver/repository/testdata/symlinks/bam @@ -0,0 +1 @@ +baz \ No newline at end of file diff --git a/reposerver/repository/testdata/symlinks/bar b/reposerver/repository/testdata/symlinks/bar new file mode 120000 index 0000000000000..19102815663d2 --- /dev/null +++ b/reposerver/repository/testdata/symlinks/bar @@ -0,0 +1 @@ +foo \ No newline at end of file diff --git a/reposerver/repository/testdata/symlinks/baz b/reposerver/repository/testdata/symlinks/baz new file mode 120000 index 0000000000000..ba0e162e1c474 --- /dev/null +++ b/reposerver/repository/testdata/symlinks/baz @@ -0,0 +1 @@ +bar \ No newline at end of file diff --git a/reposerver/repository/testdata/symlinks/foo b/reposerver/repository/testdata/symlinks/foo new file mode 100644 index 0000000000000..ce013625030ba --- /dev/null +++ b/reposerver/repository/testdata/symlinks/foo @@ -0,0 +1 @@ +hello diff --git a/resource_customizations/route53.aws.crossplane.io/ResourceRecordSet/heatlh.lua b/resource_customizations/route53.aws.crossplane.io/ResourceRecordSet/heatlh.lua new file mode 100644 index 0000000000000..0cf5253e910ff --- /dev/null +++ b/resource_customizations/route53.aws.crossplane.io/ResourceRecordSet/heatlh.lua @@ -0,0 +1,41 @@ +local hs = {} +if obj.status ~= nil then + if obj.status.conditions ~= nil then + local ready = false + local synced = false + local suspended = false + for i, condition in ipairs(obj.status.conditions) do + + if condition.type == "Ready" then + ready = condition.status == "True" + ready_message = condition.reason + elseif condition.type == "Synced" then + synced = condition.status == "True" + if condition.reason == "ReconcileError" then + synced_message = condition.message + elseif condition.reason == "ReconcilePaused" then + suspended = true + suspended_message = condition.reason + end + end + end + if ready and synced then + hs.status = "Healthy" + hs.message = ready_message + elseif synced == false and suspended == true then + hs.status = "Suspended" + hs.message = suspended_message + elseif ready == false and synced == true and suspended == false then + hs.status = "Progressing" + hs.message = "Waiting for resourcrecordset to be available" + else + hs.status = "Degraded" + hs.message = synced_message + end + return hs + end +end + +hs.status = "Progressing" +hs.message = "Waiting for resourcrecordset to be created" +return hs diff --git a/server/application/application.go b/server/application/application.go index 6c1b16545080c..5eb3ebfc5638e 100644 --- a/server/application/application.go +++ b/server/application/application.go @@ -38,6 +38,7 @@ import ( argocommon "github.com/argoproj/argo-cd/v2/common" "github.com/argoproj/argo-cd/v2/pkg/apiclient/application" + applicationType "github.com/argoproj/argo-cd/v2/pkg/apis/application" "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" appv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" appclientset "github.com/argoproj/argo-cd/v2/pkg/client/clientset/versioned" @@ -59,8 +60,6 @@ import ( "github.com/argoproj/argo-cd/v2/util/security" "github.com/argoproj/argo-cd/v2/util/session" "github.com/argoproj/argo-cd/v2/util/settings" - - applicationType "github.com/argoproj/argo-cd/v2/pkg/apis/application" ) type AppResourceTreeFn func(ctx context.Context, app *appv1.Application) (*appv1.ApplicationTree, error) @@ -453,6 +452,7 @@ func (s *Server) GetManifests(ctx context.Context, q *application.ApplicationMan return nil, security.NamespaceNotPermittedError(a.Namespace) } + manifestInfosAppVersionsIdx := -1 // defines index of spec source to take app appVersion manifestInfos := make([]*apiclient.ManifestResponse, 0) err = s.queryRepoServer(ctx, proj, func( client apiclient.RepoServerServiceClient, helmRepos []*appv1.Repository, helmCreds []*appv1.RepoCreds, helmOptions *appv1.HelmOptions, enableGenerateManifests map[string]bool, @@ -502,7 +502,7 @@ func (s *Server) GetManifests(ctx context.Context, q *application.ApplicationMan return fmt.Errorf("failed to get ref sources: %w", err) } - for _, source := range sources { + for sIdx, source := range sources { repo, err := s.db.GetRepository(ctx, source.RepoURL, proj.Name) if err != nil { return fmt.Errorf("error getting repository: %w", err) @@ -513,7 +513,7 @@ func (s *Server) GetManifests(ctx context.Context, q *application.ApplicationMan return fmt.Errorf("error getting kustomize settings: %w", err) } - kustomizeOptions, err := kustomizeSettings.GetOptions(source) + kustomizeOptions, err := kustomizeSettings.GetOptions(source, s.settingsMgr.GetKustomizeSetNamespaceEnabled()) if err != nil { return fmt.Errorf("error getting kustomize settings options: %w", err) } @@ -543,11 +543,15 @@ func (s *Server) GetManifests(ctx context.Context, q *application.ApplicationMan RefSources: refSources, AnnotationManifestGeneratePaths: a.GetAnnotation(v1alpha1.AnnotationKeyManifestGeneratePaths), InstallationID: installationID, + ApplicationMetadata: &a.ObjectMeta, }) if err != nil { return fmt.Errorf("error generating manifests: %w", err) } manifestInfos = append(manifestInfos, manifestInfo) + if source.Ref == "" && manifestInfosAppVersionsIdx < 0 { + manifestInfosAppVersionsIdx = sIdx + } } return nil }) @@ -559,7 +563,7 @@ func (s *Server) GetManifests(ctx context.Context, q *application.ApplicationMan for _, manifestInfo := range manifestInfos { for i, manifest := range manifestInfo.Manifests { obj := &unstructured.Unstructured{} - err = json.Unmarshal([]byte(manifest), obj) + err = json.Unmarshal([]byte(manifest.CompiledManifest), obj) if err != nil { return nil, fmt.Errorf("error unmarshaling manifest into unstructured: %w", err) } @@ -572,11 +576,15 @@ func (s *Server) GetManifests(ctx context.Context, q *application.ApplicationMan if err != nil { return nil, fmt.Errorf("error marshaling manifest: %w", err) } - manifestInfo.Manifests[i] = string(data) + manifestInfo.Manifests[i].CompiledManifest = string(data) } } + manifests.SourcesManifestsStartingIdx = append(manifests.SourcesManifestsStartingIdx, int32(len(manifests.Manifests))) manifests.Manifests = append(manifests.Manifests, manifestInfo.Manifests...) } + if manifestInfosAppVersionsIdx >= 0 && manifestInfos[manifestInfosAppVersionsIdx] != nil { + manifests.ApplicationVersions = manifestInfos[manifestInfosAppVersionsIdx].ApplicationVersions + } return manifests, nil } @@ -637,7 +645,7 @@ func (s *Server) GetManifestsWithFiles(stream application.ApplicationService_Get if err != nil { return fmt.Errorf("error getting kustomize settings: %w", err) } - kustomizeOptions, err := kustomizeSettings.GetOptions(a.Spec.GetSource()) + kustomizeOptions, err := kustomizeSettings.GetOptions(a.Spec.GetSource(), s.settingsMgr.GetKustomizeSetNamespaceEnabled()) if err != nil { return fmt.Errorf("error getting kustomize settings options: %w", err) } @@ -686,7 +694,7 @@ func (s *Server) GetManifestsWithFiles(stream application.ApplicationService_Get for i, manifest := range manifestInfo.Manifests { obj := &unstructured.Unstructured{} - err = json.Unmarshal([]byte(manifest), obj) + err = json.Unmarshal([]byte(manifest.CompiledManifest), obj) if err != nil { return fmt.Errorf("error unmarshaling manifest into unstructured: %w", err) } @@ -699,7 +707,7 @@ func (s *Server) GetManifestsWithFiles(stream application.ApplicationService_Get if err != nil { return fmt.Errorf("error marshaling manifest: %w", err) } - manifestInfo.Manifests[i] = string(data) + manifestInfo.Manifests[i].CompiledManifest = string(data) } } @@ -770,7 +778,7 @@ func (s *Server) Get(ctx context.Context, q *application.ApplicationQuery) (*app if err != nil { return fmt.Errorf("error getting kustomize settings: %w", err) } - kustomizeOptions, err := kustomizeSettings.GetOptions(a.Spec.GetSource()) + kustomizeOptions, err := kustomizeSettings.GetOptions(a.Spec.GetSource(), s.settingsMgr.GetKustomizeSetNamespaceEnabled()) if err != nil { return fmt.Errorf("error getting kustomize settings options: %w", err) } diff --git a/server/application/application.proto b/server/application/application.proto index 945c0c417c65c..981b5069999dc 100644 --- a/server/application/application.proto +++ b/server/application/application.proto @@ -88,6 +88,16 @@ message ApplicationManifestQueryWithFiles { optional string project = 4; } +message ApplicationValidateResponse { + optional string error = 1; + optional string entity = 2; +} + +message ApplicationRolloutRollbackResponse { + required string rollout = 1; + required int64 newRevision = 2; +} + message ApplicationManifestQueryWithFilesWrapper { oneof part { ApplicationManifestQueryWithFiles query = 1; @@ -139,6 +149,18 @@ message ApplicationSyncRequest { repeated string revisions = 15; } +message ApplicationValidationRequest { + required github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.Application application = 1; +} + +message ApplicationRolloutRollbackRequest { + required string name = 1; + required string namespace = 2; + required string rolloutName = 3; + required string rolloutNamespace = 4; + required int64 rolloutRevision = 5; +} + // ApplicationUpdateSpecRequest is a request to update application spec message ApplicationUpdateSpecRequest { required string name = 1; @@ -177,6 +199,17 @@ message ApplicationResourceRequest { optional string project = 8; } +message ChangeRevisionRequest { + required string appName = 1; + optional string namespace = 2; + optional string currentRevision = 3; + optional string previousRevision = 4; +} + +message ChangeRevisionResponse { + required string revision = 1; +} + message ApplicationResourcePatchRequest { required string name = 1; optional string namespace = 2; @@ -466,11 +499,27 @@ service ApplicationService { }; } + // Rollback application rollout + rpc RollbackApplicationRollout(ApplicationRolloutRollbackRequest) returns (ApplicationRolloutRollbackResponse) { + option (google.api.http) = { + post: "/api/v1/applications/{name}/rollout-rollback" + body: "*" + }; + } + // DeleteResource deletes a single application resource rpc DeleteResource(ApplicationResourceDeleteRequest) returns (ApplicationResponse) { option (google.api.http).delete = "/api/v1/applications/{name}/resource"; } + // Create creates an application + rpc ValidateSrcAndDst(ApplicationValidationRequest) returns (ApplicationValidateResponse) { + option (google.api.http) = { + post: "/api/v1/application-validate" + body: "application" + }; + } + // PodLogs returns stream of log entries for the specified pod. Pod rpc PodLogs(ApplicationPodLogsQuery) returns (stream LogEntry) { option (google.api.http) = { @@ -490,4 +539,8 @@ service ApplicationService { rpc ListResourceLinks(ApplicationResourceRequest) returns (LinksResponse) { option (google.api.http).get = "/api/v1/applications/{name}/resource/links"; } + + rpc GetChangeRevision(ChangeRevisionRequest) returns (ChangeRevisionResponse) { + option (google.api.http).get = "/api/v1/application/changeRevision"; + } } diff --git a/server/application/application_rollout_rollback.go b/server/application/application_rollout_rollback.go new file mode 100644 index 0000000000000..276d6f90917ef --- /dev/null +++ b/server/application/application_rollout_rollback.go @@ -0,0 +1,225 @@ +package application + +import ( + "encoding/json" + "fmt" + + jsonpatch "github.com/evanphx/json-patch" + "golang.org/x/net/context" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + apierr "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/client-go/rest" + + "github.com/argoproj/argo-cd/v2/pkg/apiclient/application" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/util/resource" +) + +func (s *Server) RollbackApplicationRollout(ctx context.Context, q *application.ApplicationRolloutRollbackRequest) (*application.ApplicationRolloutRollbackResponse, error) { + a, err := s.appLister.Applications(*q.Namespace).Get(q.GetName()) + if err != nil { + return nil, fmt.Errorf("error getting application by name: %w", err) + } + + config, err := s.getApplicationClusterConfig(ctx, a) + if err != nil { + return nil, fmt.Errorf("error getting application(%s) cluster config: %w", a.GetName(), err) + } + + liveRolloutObj, err := s.kubectl.GetResource(ctx, config, getRolloutGVK(), q.GetRolloutName(), q.GetRolloutNamespace()) + if err != nil { + return nil, fmt.Errorf("error getting live state of rollout(%s): %w", q.GetRolloutName(), err) + } + + currentRolloutRevision := resource.GetRevision(liveRolloutObj) + targetRolloutRevision := q.GetRolloutRevision() + newRolloutRevision := currentRolloutRevision + 1 + if targetRolloutRevision == currentRolloutRevision { + return nil, fmt.Errorf("revisions are equal, rollback is redundant: %w", err) + } + if targetRolloutRevision > currentRolloutRevision { + return nil, fmt.Errorf("revision greater than latest(%d): %w", currentRolloutRevision, err) + } + + rs, err := s.getReplicaSetForRolloutRollack(ctx, config, q, a) + if err != nil { + return nil, err + } + + newRolloutObj, err := s.getNewRolloutObjForRollbackPatch(liveRolloutObj, rs) + if err != nil { + return nil, err + } + + _, err = s.patchResourceOnCluster(ctx, config, newRolloutObj, liveRolloutObj) + if err != nil { + return nil, err + } + + return &application.ApplicationRolloutRollbackResponse{ + Rollout: q.RolloutName, + NewRevision: &newRolloutRevision, + }, nil +} + +func (s *Server) getRsOfSpecificRevision(ctx context.Context, config *rest.Config, rollout *v1alpha1.ResourceNode, replicasNodes []v1alpha1.ResourceNode, toRevision int64) (*unstructured.Unstructured, error) { + var ( + latestReplicaSet *unstructured.Unstructured + latestRevision = int64(-1) + previousReplicaSet *unstructured.Unstructured + previousRevision = int64(-1) + ) + for _, rsNode := range replicasNodes { + rsliveObj, err := s.kubectl.GetResource(ctx, config, rsNode.GroupKindVersion(), rsNode.Name, rsNode.Namespace) + if err != nil { + return nil, fmt.Errorf("error getting resource: %w", err) + } + + if v := resource.GetRevision(rsliveObj); err == nil { + if toRevision == 0 { + if latestRevision < v { + // newest one we've seen so far + previousRevision = latestRevision + previousReplicaSet = latestReplicaSet + latestRevision = v + latestReplicaSet = rsliveObj + } else if previousRevision < v { + // second newest one we've seen so far + previousRevision = v + previousReplicaSet = rsliveObj + } + } else if toRevision == v { + return rsliveObj, nil + } + } + } + + if toRevision > 0 { + return nil, fmt.Errorf("unable to find specified revision %v in history", toRevision) + } + + if previousReplicaSet == nil { + return nil, fmt.Errorf("no revision found for rollout %q", rollout.Name) + } + + return previousReplicaSet, nil +} + +func (s *Server) getNewRolloutObjForRollbackPatch(liveRolloutObj *unstructured.Unstructured, rs *unstructured.Unstructured) (*unstructured.Unstructured, error) { + rsSpecTemplate, found, err := unstructured.NestedFieldCopy(rs.Object, "spec", "template") + if !found { + return nil, fmt.Errorf("failed to found replicaset %s - spec/template: %w", rs.GetName(), err) + } + if err != nil { + return nil, fmt.Errorf("failed to copy replicaset %s spec/template: %w", rs.GetName(), err) + } + rsSpecTemplateU := unstructured.Unstructured{ + Object: rsSpecTemplate.(map[string]interface{}), + } + unstructured.RemoveNestedField(rsSpecTemplateU.Object, "metadata", "labels", "rollouts-pod-template-hash") + newRolloutObj := liveRolloutObj.DeepCopy() + err = unstructured.SetNestedField(newRolloutObj.Object, rsSpecTemplateU.Object, "spec", "template") + if err != nil { + return nil, fmt.Errorf("failed to set spec/template of rollout %s: %w", liveRolloutObj.GetName(), err) + } + + return newRolloutObj, nil +} + +func (s *Server) getReplicaSetForRolloutRollack(ctx context.Context, config *rest.Config, q *application.ApplicationRolloutRollbackRequest, a *v1alpha1.Application) (*unstructured.Unstructured, error) { + tree, err := s.getAppResources(ctx, a) + if err != nil { + return nil, fmt.Errorf("error getting app resources: %w", err) + } + + rolloutGVK := getRolloutGVK() + + foundRolloutNode := tree.FindNode(rolloutGVK.Group, rolloutGVK.Kind, q.GetRolloutNamespace(), q.GetRolloutName()) + if foundRolloutNode == nil || foundRolloutNode.ResourceRef.UID == "" { + return nil, status.Errorf(codes.InvalidArgument, "%s %s %s not found as part of application %s", rolloutGVK.Kind, rolloutGVK.Group, q.GetRolloutName(), q.GetName()) + } + + childReplicaSets := foundRolloutNode.GetAllChildNodes(tree, "ReplicaSet") + + if len(childReplicaSets) == 0 { + return nil, fmt.Errorf("no related replicasets found for rollout %s: %w", q.GetRolloutName(), err) + } + + rs, err := s.getRsOfSpecificRevision(ctx, config, foundRolloutNode, childReplicaSets, q.GetRolloutRevision()) + if rs == nil { + return nil, fmt.Errorf("no related replicaset of revision %d was found for rollout %s: %w", q.GetRolloutRevision(), q.GetRolloutName(), err) + } + if err != nil { + return nil, err + } + + return rs, nil +} + +func getRolloutGVK() schema.GroupVersionKind { + return schema.GroupVersionKind{ + Group: "argoproj.io", + Version: "v1alpha1", + Kind: "Rollout", + } +} + +// lagic taken from ./application.go - RunResourceAction +func (s *Server) patchResourceOnCluster(ctx context.Context, config *rest.Config, newObj *unstructured.Unstructured, liveObj *unstructured.Unstructured) (*unstructured.Unstructured, error) { + newObjBytes, err := json.Marshal(newObj) + if err != nil { + return nil, fmt.Errorf("error marshaling new object: %w", err) + } + + liveObjBytes, err := json.Marshal(liveObj) + if err != nil { + return nil, fmt.Errorf("error marshaling live object: %w", err) + } + + diffBytes, err := jsonpatch.CreateMergePatch(liveObjBytes, newObjBytes) + if err != nil { + return nil, fmt.Errorf("error calculating merge patch: %w", err) + } + if string(diffBytes) == "{}" { + return nil, nil + } + + // The following logic detects if the resource action makes a modification to status and/or spec. + // If status was modified, we attempt to patch the status using status subresource, in case the + // CRD is configured using the status subresource feature. See: + // https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#status-subresource + // If status subresource is in use, the patch has to be split into two: + // * one to update spec (and other non-status fields) + // * the other to update only status. + nonStatusPatch, statusPatch, err := splitStatusPatch(diffBytes) + if err != nil { + return nil, fmt.Errorf("error splitting status patch: %w", err) + } + if statusPatch != nil { + _, err = s.kubectl.PatchResource(ctx, config, newObj.GroupVersionKind(), newObj.GetName(), newObj.GetNamespace(), types.MergePatchType, diffBytes, "status") + if err != nil { + if !apierr.IsNotFound(err) { + return nil, fmt.Errorf("error patching resource: %w", err) + } + // K8s API server returns 404 NotFound when the CRD does not support the status subresource + // if we get here, the CRD does not use the status subresource. We will fall back to a normal patch + } else { + // If we get here, the CRD does use the status subresource, so we must patch status and + // spec separately. update the diffBytes to the spec-only patch and fall through. + diffBytes = nonStatusPatch + } + } + if diffBytes != nil { + result, err := s.kubectl.PatchResource(ctx, config, newObj.GroupVersionKind(), newObj.GetName(), newObj.GetNamespace(), types.MergePatchType, diffBytes) + if err != nil { + return nil, fmt.Errorf("error patching resource: %w", err) + } + + return result, nil + } + return nil, nil +} diff --git a/server/application/application_validate_src_and_dest.go b/server/application/application_validate_src_and_dest.go new file mode 100644 index 0000000000000..73898c943f792 --- /dev/null +++ b/server/application/application_validate_src_and_dest.go @@ -0,0 +1,91 @@ +package application + +import ( + "context" + "fmt" + + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + apierr "k8s.io/apimachinery/pkg/api/errors" + + "github.com/argoproj/argo-cd/v2/pkg/apiclient/application" + appv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + applisters "github.com/argoproj/argo-cd/v2/pkg/client/listers/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/util/argo" + "github.com/argoproj/argo-cd/v2/util/db" +) + +func (s *Server) ValidateSrcAndDst(ctx context.Context, requset *application.ApplicationValidationRequest) (*application.ApplicationValidateResponse, error) { + app := requset.Application + proj, err := argo.GetAppProject(app, applisters.NewAppProjectLister(s.projInformer.GetIndexer()), s.ns, s.settingsMgr, s.db, ctx) + if err != nil { + entity := projectEntity + if apierr.IsNotFound(err) { + errMsg := fmt.Sprintf("application references project %s which does not exist", app.Spec.Project) + return &application.ApplicationValidateResponse{ + Error: &errMsg, + Entity: &entity, + }, nil + } + errMsg := err.Error() + return &application.ApplicationValidateResponse{ + Error: &errMsg, + Entity: &entity, + }, nil + } + + if err := validateDestination(ctx, &app.Spec.Destination, s.db); err != nil { + entity := destinationEntity + errMsg := fmt.Sprintf("application destination spec for %s is invalid: %s", app.ObjectMeta.Name, err.Error()) + return &application.ApplicationValidateResponse{ + Error: &errMsg, + Entity: &entity, + }, nil + } + var conditions []appv1.ApplicationCondition + conditions, err = argo.ValidateRepo(ctx, app, s.repoClientset, s.db, s.kubectl, proj, s.settingsMgr) + if err != nil { + entity := sourceEntity + errMsg := err.Error() + return &application.ApplicationValidateResponse{ + Error: &errMsg, + Entity: &entity, + }, nil + } + if len(conditions) > 0 { + entity := sourceEntity + errMsg := fmt.Sprintf("application spec for %s is invalid: %s", app.ObjectMeta.Name, argo.FormatAppConditions(conditions)) + return &application.ApplicationValidateResponse{ + Error: &errMsg, + Entity: &entity, + }, nil + } + return &application.ApplicationValidateResponse{ + Error: nil, + Entity: nil, + }, nil +} + +// validates destination name (argo.ValidateDestination) and server with extra logic +func validateDestination(ctx context.Context, dest *appv1.ApplicationDestination, db db.ArgoDB) error { + err := argo.ValidateDestination(ctx, dest, db) + if err != nil { + return err + } + + if dest.Server != "" { + // Ensure the k8s cluster the app is referencing, is configured in Argo CD + _, err := db.GetCluster(ctx, dest.Server) + if err != nil { + if errStatus, ok := status.FromError(err); ok && errStatus.Code() == codes.NotFound { + return fmt.Errorf("cluster '%s' has not been configured", dest.Server) + } else { + return err + } + } + } else if dest.Server == "" { + return fmt.Errorf("destination server missing from app spec") + } + + return nil +} diff --git a/server/application/cf_application.go b/server/application/cf_application.go new file mode 100644 index 0000000000000..b3ca312941752 --- /dev/null +++ b/server/application/cf_application.go @@ -0,0 +1,61 @@ +package application + +import ( + "context" + "fmt" + + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + "k8s.io/utils/ptr" + + "github.com/argoproj/argo-cd/v2/pkg/apiclient/application" + appv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/reposerver/apiclient" + "github.com/argoproj/argo-cd/v2/util/app/path" + ioutil "github.com/argoproj/argo-cd/v2/util/io" +) + +const ( + projectEntity = "project" + sourceEntity = "source" + destinationEntity = "destination" +) + +func (s *Server) GetChangeRevision(ctx context.Context, in *application.ChangeRevisionRequest) (*application.ChangeRevisionResponse, error) { + app, err := s.appLister.Applications(in.GetNamespace()).Get(in.GetAppName()) + if err != nil { + return nil, err + } + + val, ok := app.Annotations[appv1.AnnotationKeyManifestGeneratePaths] + if !ok || val == "" { + return nil, status.Errorf(codes.FailedPrecondition, "manifest generation paths not set") + } + + repo, err := s.db.GetRepository(ctx, app.Spec.GetSource().RepoURL, app.Spec.Project) + if err != nil { + return nil, fmt.Errorf("error getting repository: %w", err) + } + + closer, client, err := s.repoClientset.NewRepoServerClient() + if err != nil { + return nil, fmt.Errorf("error creating repo server client: %w", err) + } + defer ioutil.Close(closer) + + response, err := client.GetChangeRevision(ctx, &apiclient.ChangeRevisionRequest{ + AppName: in.GetAppName(), + Namespace: in.GetNamespace(), + CurrentRevision: in.GetCurrentRevision(), + PreviousRevision: in.GetPreviousRevision(), + Paths: path.GetAppRefreshPaths(app), + Repo: repo, + }) + if err != nil { + return nil, fmt.Errorf("error getting change revision: %w", err) + } + + return &application.ChangeRevisionResponse{ + Revision: ptr.To(response.Revision), + }, nil +} diff --git a/server/application/events.proto b/server/application/events.proto new file mode 100644 index 0000000000000..045aa5888de7b --- /dev/null +++ b/server/application/events.proto @@ -0,0 +1,122 @@ +syntax = "proto2"; +option go_package = "github.com/argoproj/argo-cd/v2/pkg/apiclient/events"; + +// Events Service +// +// Events Service API provides a generic event-source that allows +// listening for argo-cd events natively from argo-events. +package generic; + +import "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1/generated.proto"; +import "k8s.io/apimachinery/pkg/apis/meta/v1/generated.proto"; +import "gogoproto/gogo.proto"; +import "google/api/annotations.proto"; + +message EventSource { + // The event source name. + required string name = 1; + // The event source configuration value. + optional bytes config = 2; +} + +/** +* Represents an event +*/ +message Event { + // The event source name. + required string name = 1; + // The event payload. + required bytes payload = 2; +} + +/** +* The actual object that will be send +* with each event. +*/ +message EventPayload { + // The timestamp of the event + required string timestamp = 1 [(gogoproto.nullable) = false]; + // The object that the event is about + required bytes object = 2; + // The object source information + required ObjectSource source = 3; + // The errors of this object + repeated ObjectError errors = 4; + // A version of the application and its dependencies + optional ApplicationVersions appVersions = 5; + // A version of codefresh runtime + required string runtimeVersion = 6 [(gogoproto.nullable) = false]; +} + +/** +* Holds information about the object source +*/ +message ObjectSource { + optional string desiredManifest = 1 [(gogoproto.nullable) = false]; + optional string actualManifest = 2 [(gogoproto.nullable) = false]; + optional string gitManifest = 3 [(gogoproto.nullable) = false]; + optional string repoURL = 4 [(gogoproto.nullable) = false]; + optional string path = 5 [(gogoproto.nullable) = false]; + optional string revision = 6 [(gogoproto.nullable) = false]; // sync.revision + optional string commitMessage = 7 [(gogoproto.nullable) = false]; + optional string commitAuthor = 8 [(gogoproto.nullable) = false]; + optional k8s.io.apimachinery.pkg.apis.meta.v1.Time commitDate = 9; + optional string appName = 10 [(gogoproto.nullable) = false]; + map appLabels = 11 [(gogoproto.nullable) = false]; + optional string syncStatus = 12 [(gogoproto.nullable) = false]; + optional k8s.io.apimachinery.pkg.apis.meta.v1.Time syncStartedAt = 13 [(gogoproto.nullable) = false]; + optional k8s.io.apimachinery.pkg.apis.meta.v1.Time syncFinishedAt = 14; + optional string healthStatus = 15; + optional string healthMessage = 16; + optional string cluster = 17 [(gogoproto.nullable) = false]; // destination.server + optional int64 historyId = 18 [(gogoproto.nullable) = false]; // legacy + optional string operationSyncRevision = 19 [(gogoproto.nullable) = false]; + optional string appUID = 20 [(gogoproto.nullable) = false]; + optional string appNamespace = 21 [(gogoproto.nullable) = false]; + optional string appInstanceLabelKey = 22 [(gogoproto.nullable) = false]; + optional string trackingMethod = 23 [(gogoproto.nullable) = false]; + repeated string revisions = 24; // sync.revisions + repeated string operationSyncRevisions = 25; // syncResult.revisions + optional string clusterName = 26; // destination.name + required bool appMultiSourced = 27 [(gogoproto.nullable) = false]; + required int32 appSourceIdx = 28 [(gogoproto.nullable) = false]; +} + +/** +* Holds error information; present only when error sent with application but not resource itself +*/ +message ObjectError { + optional string type = 1 [(gogoproto.nullable) = false]; + optional string level = 2 [(gogoproto.nullable) = false]; + optional string message = 3 [(gogoproto.nullable) = false]; + optional k8s.io.apimachinery.pkg.apis.meta.v1.Time lastSeen = 4 [(gogoproto.nullable) = false]; + optional ErrorSourceReference sourceReference = 5; +} + +/** +* Holds application resource metadata to which the error related +*/ +message ErrorSourceReference { + optional string group = 1 [(gogoproto.nullable) = false]; + optional string version = 2 [(gogoproto.nullable) = false]; + required string kind = 3 [(gogoproto.nullable) = false]; + required string name = 4 [(gogoproto.nullable) = false]; + optional string namespace = 5 [(gogoproto.nullable) = false]; +} + +message Dependencies { + // Content of Chart.lock + optional string lock = 1; + // Content of Chart.yaml + optional string deps = 2; + // Content of requirements.yaml + optional string requirements = 3; +} + +message ApplicationVersions { + // Application version presented by single value + optional string appVersion = 1; + // Yaml content of dependencies + optional Dependencies dependencies = 2; +} + diff --git a/server/cache/cf_cache.go b/server/cache/cf_cache.go new file mode 100644 index 0000000000000..a3ec2db991071 --- /dev/null +++ b/server/cache/cf_cache.go @@ -0,0 +1,35 @@ +package cache + +import ( + "fmt" + "time" + + appv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" +) + +func (c *Cache) SetLastApplicationEvent(a *appv1.Application, exp time.Duration) error { + return c.cache.SetItem(lastApplicationEventKey(a), a, exp, false) +} + +func (c *Cache) GetLastApplicationEvent(a *appv1.Application) (*appv1.Application, error) { + cachedApp := appv1.Application{} + return &cachedApp, c.cache.GetItem(lastApplicationEventKey(a), &cachedApp) +} + +func (c *Cache) SetLastResourceEvent(a *appv1.Application, rs appv1.ResourceStatus, exp time.Duration, revision string) error { + return c.cache.SetItem(lastResourceEventKey(a, rs, revision), rs, exp, false) +} + +func (c *Cache) GetLastResourceEvent(a *appv1.Application, rs appv1.ResourceStatus, revision string) (appv1.ResourceStatus, error) { + res := appv1.ResourceStatus{} + return res, c.cache.GetItem(lastResourceEventKey(a, rs, revision), &res) +} + +func lastApplicationEventKey(a *appv1.Application) string { + return fmt.Sprintf("app|%s/%s|last-sent-event", a.Namespace, a.Name) +} + +func lastResourceEventKey(a *appv1.Application, rs appv1.ResourceStatus, revision string) string { + return fmt.Sprintf("app|%s/%s|%s|res|%s/%s/%s/%s/%s|last-sent-event", + a.Namespace, a.Name, revision, rs.Group, rs.Version, rs.Kind, rs.Name, rs.Namespace) +} diff --git a/server/repository/repository.go b/server/repository/repository.go index d671188b65696..bcb445634344b 100644 --- a/server/repository/repository.go +++ b/server/repository/repository.go @@ -364,7 +364,7 @@ func (s *Server) GetAppDetails(ctx context.Context, q *repositorypkg.RepoAppDeta if err != nil { return nil, err } - kustomizeOptions, err := kustomizeSettings.GetOptions(*q.Source) + kustomizeOptions, err := kustomizeSettings.GetOptions(*q.Source, s.settings.GetKustomizeSetNamespaceEnabled()) if err != nil { return nil, err } diff --git a/sonar-project.properties b/sonar-project.properties index 21dad92e68837..7cdf0f1dfc4fc 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -1,5 +1,5 @@ -sonar.projectKey=argoproj_argo-cd -sonar.organization=argoproj +sonar.projectKey=argo-cd +sonar.organization=codefresh-io # This is the name and version displayed in the SonarCloud UI. sonar.projectName=argo-cd diff --git a/test/e2e/app_management_ns_test.go b/test/e2e/app_management_ns_test.go index 328d252f66703..4e5c72872ac88 100644 --- a/test/e2e/app_management_ns_test.go +++ b/test/e2e/app_management_ns_test.go @@ -655,7 +655,7 @@ func TestNamespacedAppWithSecrets(t *testing.T) { }) errors.CheckError(err) - for _, manifest := range manifests.Manifests { + for _, manifest := range manifests.GetCompiledManifests() { assetSecretDataHidden(t, manifest) } diff --git a/test/e2e/app_management_test.go b/test/e2e/app_management_test.go index 3b471bc304718..9e873f370741b 100644 --- a/test/e2e/app_management_test.go +++ b/test/e2e/app_management_test.go @@ -808,7 +808,7 @@ func TestAppWithSecrets(t *testing.T) { errors.CheckError(err) for _, manifest := range manifests.Manifests { - assetSecretDataHidden(t, manifest) + assetSecretDataHidden(t, manifest.CompiledManifest) } diffOutput := FailOnErr(RunCli("app", "diff", app.Name)).(string) diff --git a/test/e2e/project_management_test.go b/test/e2e/project_management_test.go index 169227eea52a5..3c9d2181edba6 100644 --- a/test/e2e/project_management_test.go +++ b/test/e2e/project_management_test.go @@ -533,6 +533,8 @@ func TestGetVirtualProjectNoMatch(t *testing.T) { "--path", guestbookPath, "--project", proj.Name, "--dest-server", v1alpha1.KubernetesInternalAPIServerAddr, "--dest-namespace", fixture.DeploymentNamespace()) require.NoError(t, err) + time.Sleep(1 * time.Second) + // App trying to sync a resource which is not blacked listed anywhere _, err = fixture.RunCli("app", "sync", fixture.Name(), "--resource", "apps:Deployment:guestbook-ui", "--timeout", strconv.Itoa(10)) require.NoError(t, err) @@ -569,6 +571,8 @@ func TestGetVirtualProjectMatch(t *testing.T) { "--path", guestbookPath, "--project", proj.Name, "--dest-server", v1alpha1.KubernetesInternalAPIServerAddr, "--dest-namespace", fixture.DeploymentNamespace()) require.NoError(t, err) + time.Sleep(1 * time.Second) + // App trying to sync a resource which is not blacked listed anywhere _, err = fixture.RunCli("app", "sync", fixture.Name(), "--resource", "apps:Deployment:guestbook-ui", "--timeout", strconv.Itoa(10)) require.ErrorContains(t, err, "blocked by sync window") diff --git a/test/e2e/testdata/helm-with-multiple-dependencies/Chart.yaml b/test/e2e/testdata/helm-with-multiple-dependencies/Chart.yaml index f7f144d20e123..fc1982761746c 100644 --- a/test/e2e/testdata/helm-with-multiple-dependencies/Chart.yaml +++ b/test/e2e/testdata/helm-with-multiple-dependencies/Chart.yaml @@ -1,11 +1,7 @@ apiVersion: v2 -name: helm-with-multiple-dependencies +name: helm-with-dependencies version: v1.0.0 dependencies: - name: helm repository: "https://localhost:9444/argo-e2e/testdata.git/helm-repo/local" version: v1.0.0 - - name: helm - repository: "https://localhost:9444/argo-e2e/testdata.git/helm-repo/local2" - version: v1.0.0 - alias: helm2 \ No newline at end of file diff --git a/util/argo/argo.go b/util/argo/argo.go index 90bf1c809959b..c9050a9d38089 100644 --- a/util/argo/argo.go +++ b/util/argo/argo.go @@ -802,7 +802,7 @@ func verifyGenerateManifests( }) continue } - kustomizeOptions, err := kustomizeSettings.GetOptions(source) + kustomizeOptions, err := kustomizeSettings.GetOptions(source, settingsMgr.GetKustomizeSetNamespaceEnabled()) if err != nil { conditions = append(conditions, argoappv1.ApplicationCondition{ Type: argoappv1.ApplicationConditionInvalidSpecError, @@ -845,6 +845,7 @@ func verifyGenerateManifests( ProjectSourceRepos: proj.Spec.SourceRepos, AnnotationManifestGeneratePaths: app.GetAnnotation(argoappv1.AnnotationKeyManifestGeneratePaths), InstallationID: installationID, + ApplicationMetadata: &app.ObjectMeta, } req.Repo.CopyCredentialsFromRepo(repoRes) req.Repo.CopySettingsFrom(repoRes) diff --git a/util/git/cf_client.go b/util/git/cf_client.go new file mode 100644 index 0000000000000..efed7e0c0aaaa --- /dev/null +++ b/util/git/cf_client.go @@ -0,0 +1,45 @@ +package git + +import ( + "fmt" + "strings" +) + +func (m *nativeGitClient) ListRevisions(revision string, targetRevision string) ([]string, error) { + // it happens when app just created and there is no revision yet + if revision == "" { + return []string{targetRevision}, nil + } + + if !IsCommitSHA(revision) || !IsCommitSHA(targetRevision) { + return nil, fmt.Errorf("invalid revision provided, must be SHA") + } + + if revision == targetRevision { + return []string{revision}, nil + } + + out, err := m.runCmd("rev-list", "--ancestry-path", fmt.Sprintf("%s..%s", revision, targetRevision)) + if err != nil { + return nil, err + } + ss := strings.Split(out, "\n") + return ss, nil +} + +func (m *nativeGitClient) DiffTree(targetRevision string) ([]string, error) { + if !IsCommitSHA(targetRevision) { + return []string{}, fmt.Errorf("invalid revision provided, must be SHA") + } + out, err := m.runCmd("diff-tree", "--no-commit-id", "--name-only", "-r", targetRevision) + if err != nil { + return nil, fmt.Errorf("failed to diff %s: %w", targetRevision, err) + } + + if out == "" { + return []string{}, nil + } + + files := strings.Split(out, "\n") + return files, nil +} diff --git a/util/git/client.go b/util/git/client.go index 0b9ab11b79eee..aff297b8f2ae5 100644 --- a/util/git/client.go +++ b/util/git/client.go @@ -91,6 +91,8 @@ type Client interface { RemoveContents() (string, error) // CommitAndPush commits and pushes changes to the target branch. CommitAndPush(branch, message string) (string, error) + ListRevisions(revision string, targetRevision string) ([]string, error) + DiffTree(targetRevision string) ([]string, error) } type EventHandlers struct { diff --git a/util/git/mocks/Client.go b/util/git/mocks/Client.go index 9357264e3bdd6..86c21d98ea793 100644 --- a/util/git/mocks/Client.go +++ b/util/git/mocks/Client.go @@ -182,6 +182,36 @@ func (_m *Client) CommitSHA() (string, error) { return r0, r1 } +// DiffTree provides a mock function with given fields: targetRevision +func (_m *Client) DiffTree(targetRevision string) ([]string, error) { + ret := _m.Called(targetRevision) + + if len(ret) == 0 { + panic("no return value specified for DiffTree") + } + + var r0 []string + var r1 error + if rf, ok := ret.Get(0).(func(string) ([]string, error)); ok { + return rf(targetRevision) + } + if rf, ok := ret.Get(0).(func(string) []string); ok { + r0 = rf(targetRevision) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]string) + } + } + + if rf, ok := ret.Get(1).(func(string) error); ok { + r1 = rf(targetRevision) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + // Fetch provides a mock function with given fields: revision func (_m *Client) Fetch(revision string) error { ret := _m.Called(revision) @@ -254,6 +284,36 @@ func (_m *Client) IsRevisionPresent(revision string) bool { return r0 } +// ListRevisions provides a mock function with given fields: revision, targetRevision +func (_m *Client) ListRevisions(revision string, targetRevision string) ([]string, error) { + ret := _m.Called(revision, targetRevision) + + if len(ret) == 0 { + panic("no return value specified for ListRevisions") + } + + var r0 []string + var r1 error + if rf, ok := ret.Get(0).(func(string, string) ([]string, error)); ok { + return rf(revision, targetRevision) + } + if rf, ok := ret.Get(0).(func(string, string) []string); ok { + r0 = rf(revision, targetRevision) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]string) + } + } + + if rf, ok := ret.Get(1).(func(string, string) error); ok { + r1 = rf(revision, targetRevision) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + // LsFiles provides a mock function with given fields: path, enableNewGitFileGlobbing func (_m *Client) LsFiles(path string, enableNewGitFileGlobbing bool) ([]string, error) { ret := _m.Called(path, enableNewGitFileGlobbing) diff --git a/util/kustomize/cf_kustomize.go b/util/kustomize/cf_kustomize.go new file mode 100644 index 0000000000000..09914cfacb32c --- /dev/null +++ b/util/kustomize/cf_kustomize.go @@ -0,0 +1,60 @@ +package kustomize + +import ( + "fmt" + "net/url" + "strings" + + log "github.com/sirupsen/logrus" + + "github.com/argoproj/argo-cd/v2/util/git" + + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" +) + +type ResolveRevisionFunc func(repo, revision string, creds git.Creds) (string, error) + +func (k *kustomize) GetCacheKeyWithComponents(revision string, source *v1alpha1.ApplicationSourceKustomize, resolveRevisionFunc ResolveRevisionFunc) (string, error) { + cacheKey := "" + + revisionsToResolve := map[string]string{} + + for _, c := range source.Components { + _, err := url.Parse(c) + if err != nil { + continue // local files are not part of the cache key + } + + _, _, path, ref := parseGitURL(c) + if ref == "" { + ref = "HEAD" + } + + cleanRepoURL := c + if path != "" { + suffixToTrim := c + if searchedValueIndex := strings.Index(c, path); searchedValueIndex != -1 { + suffixToTrim = c[:searchedValueIndex] + } + cleanRepoURL = strings.TrimSuffix(suffixToTrim, "/") + } + + revisionsToResolve[cleanRepoURL] = ref + } + + for component, ref := range revisionsToResolve { + rev, err := resolveRevisionFunc(component, ref, k.creds) + if err != nil { + log.WithError(err). + WithField("url", component). + Warn("failed to resolve revision of component from url, ignoring in cache key") + continue + } + if cacheKey != "" { + cacheKey += "|" + } + cacheKey += fmt.Sprintf("%s|%s", component, rev) + } + + return fmt.Sprintf("%s|%s", revision, cacheKey), nil +} diff --git a/util/kustomize/kustomize.go b/util/kustomize/kustomize.go index 3fb15a64d3b56..608aceba89864 100644 --- a/util/kustomize/kustomize.go +++ b/util/kustomize/kustomize.go @@ -36,7 +36,12 @@ type BuildOpts struct { // Kustomize provides wrapper functionality around the `kustomize` command. type Kustomize interface { // Build returns a list of unstructured objects from a `kustomize build` command and extract supported parameters - Build(opts *v1alpha1.ApplicationSourceKustomize, kustomizeOptions *v1alpha1.KustomizeOptions, envVars *v1alpha1.Env, buildOpts *BuildOpts) ([]*unstructured.Unstructured, []Image, []string, error) + Build(opts *v1alpha1.ApplicationSourceKustomize, kustomizeOptions *v1alpha1.KustomizeOptions, envVars *v1alpha1.Env, buildOpts *BuildOpts, namespace string) ([]*unstructured.Unstructured, []Image, []string, error) + // Codefresh-fix + // GetCacheKeyWithComponents returns a cache key that takes remote components repositories in consideration and + // not just the repository that contains the base Kustomization file. This is required if we want to rebuild the + // manifests everytime one of the component repositories change and not wait for a hard refresh. + GetCacheKeyWithComponents(revision string, source *v1alpha1.ApplicationSourceKustomize, resolveRevisionFunc ResolveRevisionFunc) (string, error) } // NewKustomizeApp create a new wrapper to run commands on the `kustomize` command-line tool. @@ -121,7 +126,7 @@ func mapToEditAddArgs(val map[string]string) []string { return args } -func (k *kustomize) Build(opts *v1alpha1.ApplicationSourceKustomize, kustomizeOptions *v1alpha1.KustomizeOptions, envVars *v1alpha1.Env, buildOpts *BuildOpts) ([]*unstructured.Unstructured, []Image, []string, error) { +func (k *kustomize) Build(opts *v1alpha1.ApplicationSourceKustomize, kustomizeOptions *v1alpha1.KustomizeOptions, envVars *v1alpha1.Env, buildOpts *BuildOpts, namespace string) ([]*unstructured.Unstructured, []Image, []string, error) { // commands stores all the commands that were run as part of this build. var commands []string @@ -159,6 +164,15 @@ func (k *kustomize) Build(opts *v1alpha1.ApplicationSourceKustomize, kustomizeOp env = append(env, environ...) + if kustomizeOptions != nil && kustomizeOptions.SetNamespace && namespace != "" { + cmd := exec.Command(k.getBinaryPath(), "edit", "set", "namespace", "--", namespace) + cmd.Dir = k.path + _, err := executil.Run(cmd) + if err != nil { + return nil, nil, nil, err + } + } + if opts != nil { if opts.NamePrefix != "" { cmd := exec.Command(k.getBinaryPath(), "edit", "set", "nameprefix", "--", opts.NamePrefix) diff --git a/util/kustomize/kustomize_test.go b/util/kustomize/kustomize_test.go index f58e58d2c2632..db7722a6bbb10 100644 --- a/util/kustomize/kustomize_test.go +++ b/util/kustomize/kustomize_test.go @@ -74,7 +74,7 @@ func TestKustomizeBuild(t *testing.T) { } objs, images, _, err := kustomize.Build(&kustomizeSource, nil, env, &BuildOpts{ KubeVersion: "1.27", APIVersions: []string{"foo", "bar"}, - }) + }, "") require.NoError(t, err) if err != nil { assert.Len(t, objs, 2) @@ -137,7 +137,7 @@ func TestFailKustomizeBuild(t *testing.T) { }, }, } - _, _, _, err = kustomize.Build(&kustomizeSource, nil, nil, nil) + _, _, _, err = kustomize.Build(&kustomizeSource, nil, nil, nil, "") assert.EqualError(t, err, "expected integer value for count. Received: garbage") } @@ -232,7 +232,7 @@ func TestKustomizeBuildForceCommonLabels(t *testing.T) { appPath, err := testDataDir(t, tc.TestData) require.NoError(t, err) kustomize := NewKustomizeApp(appPath, appPath, git.NopCreds{}, "", "", "", "") - objs, _, _, err := kustomize.Build(&tc.KustomizeSource, nil, tc.Env, nil) + objs, _, _, err := kustomize.Build(&tc.KustomizeSource, nil, tc.Env, nil, "") switch tc.ExpectErr { case true: require.Error(t, err) @@ -324,7 +324,7 @@ func TestKustomizeBuildForceCommonAnnotations(t *testing.T) { appPath, err := testDataDir(t, tc.TestData) require.NoError(t, err) kustomize := NewKustomizeApp(appPath, appPath, git.NopCreds{}, "", "", "", "") - objs, _, _, err := kustomize.Build(&tc.KustomizeSource, nil, tc.Env, nil) + objs, _, _, err := kustomize.Build(&tc.KustomizeSource, nil, tc.Env, nil, "") switch tc.ExpectErr { case true: require.Error(t, err) @@ -391,7 +391,7 @@ func TestKustomizeLabelWithoutSelector(t *testing.T) { appPath, err := testDataDir(t, tc.TestData) require.NoError(t, err) kustomize := NewKustomizeApp(appPath, appPath, git.NopCreds{}, "", "", "", "") - objs, _, _, err := kustomize.Build(&tc.KustomizeSource, nil, tc.Env, nil) + objs, _, _, err := kustomize.Build(&tc.KustomizeSource, nil, tc.Env, nil, "") switch tc.ExpectErr { case true: @@ -427,7 +427,7 @@ func TestKustomizeCustomVersion(t *testing.T) { env := &v1alpha1.Env{ &v1alpha1.EnvEntry{Name: "ARGOCD_APP_NAME", Value: "argo-cd-tests"}, } - objs, images, _, err := kustomize.Build(&kustomizeSource, nil, env, nil) + objs, images, _, err := kustomize.Build(&kustomizeSource, nil, env, nil, "") require.NoError(t, err) if err != nil { assert.Len(t, objs, 2) @@ -447,7 +447,7 @@ func TestKustomizeBuildComponents(t *testing.T) { kustomizeSource := v1alpha1.ApplicationSourceKustomize{ Components: []string{"./components"}, } - objs, _, _, err := kustomize.Build(&kustomizeSource, nil, nil, nil) + objs, _, _, err := kustomize.Build(&kustomizeSource, nil, nil, nil, "") require.NoError(t, err) obj := objs[0] assert.Equal(t, "nginx-deployment", obj.GetName()) @@ -480,7 +480,7 @@ func TestKustomizeBuildPatches(t *testing.T) { }, }, } - objs, _, _, err := kustomize.Build(&kustomizeSource, nil, nil, nil) + objs, _, _, err := kustomize.Build(&kustomizeSource, nil, nil, nil, "") require.NoError(t, err) obj := objs[0] containers, found, err := unstructured.NestedSlice(obj.Object, "spec", "template", "spec", "containers") @@ -533,6 +533,6 @@ func TestFailKustomizeBuildPatches(t *testing.T) { }, } - _, _, _, err = kustomize.Build(&kustomizeSource, nil, nil, nil) + _, _, _, err = kustomize.Build(&kustomizeSource, nil, nil, nil, "") require.EqualError(t, err, "kustomization file not found in the path") } diff --git a/util/kustomize/repospec.go b/util/kustomize/repospec.go new file mode 100644 index 0000000000000..839483795ee86 --- /dev/null +++ b/util/kustomize/repospec.go @@ -0,0 +1,151 @@ +// The following file was copied from https://github.com/kubernetes-sigs/kustomize/blob/master/api/internal/git/repospec.go +// and modified to expose the ParseGitUrl function +// +// Copyright 2019 The Kubernetes Authors. +// SPDX-License-Identifier: Apache-2.0 +package kustomize + +import ( + "net/url" + "strings" +) + +const ( + gitSuffix = ".git" + gitDelimiter = "_git/" +) + +// From strings like git@github.com:someOrg/someRepo.git or +// https://github.com/someOrg/someRepo?ref=someHash, extract +// the parts. +func parseGitURL(n string) ( + host string, orgRepo string, path string, gitRef string, +) { + if strings.Contains(n, gitDelimiter) { + index := strings.Index(n, gitDelimiter) + // Adding _git/ to host + host = normalizeGitHostSpec(n[:index+len(gitDelimiter)]) + orgRepo = strings.Split(strings.Split(n[index+len(gitDelimiter):], "/")[0], "?")[0] + path, gitRef = peelQuery(n[index+len(gitDelimiter)+len(orgRepo):]) + return + } + host, n = parseHostSpec(n) + if strings.Contains(n, gitSuffix) { + index := strings.Index(n, gitSuffix) + orgRepo = n[0:index] + n = n[index+len(gitSuffix):] + if len(n) > 0 && n[0] == '/' { + n = n[1:] + } + path, gitRef = peelQuery(n) + return + } + + i := strings.Index(n, "/") + if i < 1 { + path, gitRef = peelQuery(n) + return + } + j := strings.Index(n[i+1:], "/") + if j >= 0 { + j += i + 1 + orgRepo = n[:j] + path, gitRef = peelQuery(n[j+1:]) + return + } + path = "" + orgRepo, gitRef = peelQuery(n) + return host, orgRepo, path, gitRef +} + +func peelQuery(arg string) (string, string) { + // Parse the given arg into a URL. In the event of a parse failure, return + // our defaults. + parsed, err := url.Parse(arg) + if err != nil { + return arg, "" + } + values := parsed.Query() + + // ref is the desired git ref to target. Can be specified by in a git URL + // with ?ref= or ?version=, although ref takes precedence. + ref := values.Get("version") + if queryValue := values.Get("ref"); queryValue != "" { + ref = queryValue + } + + return parsed.Path, ref +} + +func parseHostSpec(n string) (string, string) { + var host string + // Start accumulating the host part. + for _, p := range []string{ + // Order matters here. + "git::", "gh:", "ssh://", "https://", "http://", + "git@", "github.com:", "github.com/", + } { + if len(p) < len(n) && strings.ToLower(n[:len(p)]) == p { + n = n[len(p):] + host += p + } + } + if host == "git@" { + i := strings.Index(n, "/") + if i > -1 { + host += n[:i+1] + n = n[i+1:] + } else { + i = strings.Index(n, ":") + if i > -1 { + host += n[:i+1] + n = n[i+1:] + } + } + return host, n + } + + // If host is a http(s) or ssh URL, grab the domain part. + for _, p := range []string{ + "ssh://", "https://", "http://", + } { + if strings.HasSuffix(host, p) { + i := strings.Index(n, "/") + if i > -1 { + host += n[0 : i+1] + n = n[i+1:] + } + break + } + } + + return normalizeGitHostSpec(host), n +} + +func normalizeGitHostSpec(host string) string { + s := strings.ToLower(host) + if strings.Contains(s, "github.com") { + if strings.Contains(s, "git@") || strings.Contains(s, "ssh:") { + host = "git@github.com:" + } else { + host = "https://github.com/" + } + } + if strings.HasPrefix(s, "git::") { + host = strings.TrimPrefix(s, "git::") + } + return host +} + +// The format of Azure repo URL is documented +// https://docs.microsoft.com/en-us/azure/devops/repos/git/clone?view=vsts&tabs=visual-studio#clone_url +func isAzureHost(host string) bool { + return strings.Contains(host, "dev.azure.com") || + strings.Contains(host, "visualstudio.com") +} + +// The format of AWS repo URL is documented +// https://docs.aws.amazon.com/codecommit/latest/userguide/regions.html +func isAWSHost(host string) bool { + return strings.Contains(host, "amazonaws.com") +} diff --git a/util/kustomize/repospec_test.go b/util/kustomize/repospec_test.go new file mode 100644 index 0000000000000..1a18064071033 --- /dev/null +++ b/util/kustomize/repospec_test.go @@ -0,0 +1,250 @@ +// The following file was copied from https://github.com/kubernetes-sigs/kustomize/blob/master/api/internal/git/repospec.go +// and modified to expose the ParseGitUrl function +// +// Copyright 2019 The Kubernetes Authors. +// SPDX-License-Identifier: Apache-2.0 + +package kustomize + +import ( + "fmt" + "path/filepath" + "testing" + + "github.com/stretchr/testify/assert" +) + +const ( + refQuery = "?ref=" +) + +var orgRepos = []string{"someOrg/someRepo", "kubernetes/website"} + +var pathNames = []string{"README.md", "foo/krusty.txt", ""} + +var hrefArgs = []string{"someBranch", "master", "v0.1.0", ""} + +var hostNamesRawAndNormalized = [][]string{ + {"gh:", "gh:"}, + {"GH:", "gh:"}, + {"gitHub.com/", "https://github.com/"}, + {"github.com:", "https://github.com/"}, + {"http://github.com/", "https://github.com/"}, + {"https://github.com/", "https://github.com/"}, + {"hTTps://github.com/", "https://github.com/"}, + {"https://git-codecommit.us-east-2.amazonaws.com/", "https://git-codecommit.us-east-2.amazonaws.com/"}, + {"https://fabrikops2.visualstudio.com/", "https://fabrikops2.visualstudio.com/"}, + {"ssh://git.example.com:7999/", "ssh://git.example.com:7999/"}, + {"git::https://gitlab.com/", "https://gitlab.com/"}, + {"git::http://git.example.com/", "http://git.example.com/"}, + {"git::https://git.example.com/", "https://git.example.com/"}, + {"git@github.com:", "git@github.com:"}, + {"git@github.com/", "git@github.com:"}, +} + +func makeURL(hostFmt, orgRepo, path, href string) string { + if len(path) > 0 { + orgRepo = filepath.Join(orgRepo, path) + } + url := hostFmt + orgRepo + if href != "" { + url += refQuery + href + } + return url +} + +func TestNewRepoSpecFromUrl(t *testing.T) { + var bad [][]string + for _, tuple := range hostNamesRawAndNormalized { + hostRaw := tuple[0] + hostSpec := tuple[1] + for _, orgRepo := range orgRepos { + for _, pathName := range pathNames { + for _, hrefArg := range hrefArgs { + uri := makeURL(hostRaw, orgRepo, pathName, hrefArg) + host, org, path, ref := parseGitURL(uri) + if host != hostSpec { + bad = append(bad, []string{"host", uri, host, hostSpec}) + } + if org != orgRepo { + bad = append(bad, []string{"orgRepo", uri, org, orgRepo}) + } + if path != pathName { + bad = append(bad, []string{"path", uri, path, pathName}) + } + if ref != hrefArg { + bad = append(bad, []string{"ref", uri, ref, hrefArg}) + } + } + } + } + } + if len(bad) > 0 { + for _, tuple := range bad { + fmt.Printf("\n"+ + " from uri: %s\n"+ + " actual %4s: %s\n"+ + "expected %4s: %s\n", + tuple[1], tuple[0], tuple[2], tuple[0], tuple[3]) + } + t.Fail() + } +} + +func TestIsAzureHost(t *testing.T) { + testcases := []struct { + input string + expect bool + }{ + { + input: "https://git-codecommit.us-east-2.amazonaws.com", + expect: false, + }, + { + input: "ssh://git-codecommit.us-east-2.amazonaws.com", + expect: false, + }, + { + input: "https://fabrikops2.visualstudio.com/", + expect: true, + }, + { + input: "https://dev.azure.com/myorg/myproject/", + expect: true, + }, + } + for _, testcase := range testcases { + actual := isAzureHost(testcase.input) + if actual != testcase.expect { + t.Errorf("IsAzureHost: expected %v, but got %v on %s", testcase.expect, actual, testcase.input) + } + } +} + +func TestPeelQuery(t *testing.T) { + testcases := map[string]struct { + input string + path string + ref string + }{ + "t1": { + // All empty. + input: "somerepos", + path: "somerepos", + ref: "", + }, + "t2": { + input: "somerepos?ref=v1.0.0", + path: "somerepos", + ref: "v1.0.0", + }, + "t3": { + input: "somerepos?version=master", + path: "somerepos", + ref: "master", + }, + "t4": { + // A ref value takes precedence over a version value. + input: "somerepos?version=master&ref=v1.0.0", + path: "somerepos", + ref: "v1.0.0", + }, + "t5": { + // Empty submodules value uses default. + input: "somerepos?version=master&submodules=", + path: "somerepos", + ref: "master", + }, + "t6": { + // Malformed submodules value uses default. + input: "somerepos?version=master&submodules=maybe", + path: "somerepos", + ref: "master", + }, + "t7": { + input: "somerepos?version=master&submodules=true", + path: "somerepos", + ref: "master", + }, + "t8": { + input: "somerepos?version=master&submodules=false", + path: "somerepos", + ref: "master", + }, + "t9": { + // Empty timeout value uses default. + input: "somerepos?version=master&timeout=", + path: "somerepos", + ref: "master", + }, + "t10": { + // Malformed timeout value uses default. + input: "somerepos?version=master&timeout=jiffy", + path: "somerepos", + ref: "master", + }, + "t11": { + // Zero timeout value uses default. + input: "somerepos?version=master&timeout=0", + path: "somerepos", + ref: "master", + }, + "t12": { + input: "somerepos?version=master&timeout=0s", + path: "somerepos", + ref: "master", + }, + "t13": { + input: "somerepos?version=master&timeout=61", + path: "somerepos", + ref: "master", + }, + "t14": { + input: "somerepos?version=master&timeout=1m1s", + path: "somerepos", + ref: "master", + }, + "t15": { + input: "somerepos?version=master&submodules=false&timeout=1m1s", + path: "somerepos", + ref: "master", + }, + } + for tn, tc := range testcases { + t.Run(tn, func(t *testing.T) { + path, ref := peelQuery(tc.input) + assert.Equal(t, tc.path, path, "path mismatch") + assert.Equal(t, tc.ref, ref, "ref mismatch") + }) + } +} + +func TestIsAWSHost(t *testing.T) { + testcases := []struct { + input string + expect bool + }{ + { + input: "https://git-codecommit.us-east-2.amazonaws.com", + expect: true, + }, + { + input: "ssh://git-codecommit.us-east-2.amazonaws.com", + expect: true, + }, + { + input: "git@github.com:", + expect: false, + }, + { + input: "http://github.com/", + expect: false, + }, + } + for _, testcase := range testcases { + actual := isAWSHost(testcase.input) + if actual != testcase.expect { + t.Errorf("IsAWSHost: expected %v, but got %v on %s", testcase.expect, actual, testcase.input) + } + } +} diff --git a/util/notification/argocd/service.go b/util/notification/argocd/service.go index acb355a8d2db4..0f26988685e46 100644 --- a/util/notification/argocd/service.go +++ b/util/notification/argocd/service.go @@ -71,7 +71,7 @@ func (svc *argoCDService) getKustomizeOptions(source *v1alpha1.ApplicationSource if err != nil { return nil, err } - return kustomizeSettings.GetOptions(*source) + return kustomizeSettings.GetOptions(*source, svc.settingsMgr.GetKustomizeSetNamespaceEnabled()) } func (svc *argoCDService) GetAppDetails(ctx context.Context, app *v1alpha1.Application) (*shared.AppDetail, error) { diff --git a/util/settings/cf_settings.go b/util/settings/cf_settings.go new file mode 100644 index 0000000000000..b38f767aca4ea --- /dev/null +++ b/util/settings/cf_settings.go @@ -0,0 +1,13 @@ +package settings + +func (mgr *SettingsManager) GetKustomizeSetNamespaceEnabled() bool { + argoCDCM, err := mgr.getConfigMap() + if err != nil { + return false + } + kustomizeSetNamespaceEnabled := argoCDCM.Data[kustomizeSetNamespaceEnabledKey] + if kustomizeSetNamespaceEnabled == "" { + return false + } + return kustomizeSetNamespaceEnabled == "true" +} diff --git a/util/settings/settings.go b/util/settings/settings.go index 37057418a9766..6e4cd78f97bb5 100644 --- a/util/settings/settings.go +++ b/util/settings/settings.go @@ -129,6 +129,8 @@ type ArgoCDSettings struct { // ImpersonationEnabled indicates whether Application sync privileges can be decoupled from control plane // privileges using impersonation ImpersonationEnabled bool `json:"impersonationEnabled"` + // KustomizeSetNamespaceEnabled enable set namespace for kustomize by default + KustomizeSetNamespaceEnabled bool `json:"kustomizeSetNamespaceEnabled"` } type GoogleAnalytics struct { @@ -284,7 +286,7 @@ var ( } ) -func (ks *KustomizeSettings) GetOptions(source v1alpha1.ApplicationSource) (*v1alpha1.KustomizeOptions, error) { +func (ks *KustomizeSettings) GetOptions(source v1alpha1.ApplicationSource, setNamespace bool) (*v1alpha1.KustomizeOptions, error) { binaryPath := "" buildOptions := "" if source.Kustomize != nil && source.Kustomize.Version != "" { @@ -306,6 +308,7 @@ func (ks *KustomizeSettings) GetOptions(source v1alpha1.ApplicationSource) (*v1a return &v1alpha1.KustomizeOptions{ BuildOptions: buildOptions, BinaryPath: binaryPath, + SetNamespace: setNamespace, }, nil } @@ -537,6 +540,8 @@ const ( RespectRBACValueNormal = "normal" // impersonationEnabledKey is the key to configure whether the application sync decoupling through impersonation feature is enabled impersonationEnabledKey = "application.sync.impersonation.enabled" + // kustomizeSetNamespaceEnabledKey is the key to configure if kustomize set namespace should be executed + kustomizeSetNamespaceEnabledKey = "kustomize.setNamespace.enabled" ) const ( diff --git a/util/settings/settings_test.go b/util/settings/settings_test.go index d76234b8ae0c1..b678bf597fc09 100644 --- a/util/settings/settings_test.go +++ b/util/settings/settings_test.go @@ -846,12 +846,12 @@ func TestKustomizeSettings_GetOptions(t *testing.T) { t.Run("VersionDoesNotExist", func(t *testing.T) { _, err := settings.GetOptions(v1alpha1.ApplicationSource{ Kustomize: &v1alpha1.ApplicationSourceKustomize{Version: "v4"}, - }) + }, true) require.Error(t, err) }) t.Run("DefaultBuildOptions", func(t *testing.T) { - ver, err := settings.GetOptions(v1alpha1.ApplicationSource{}) + ver, err := settings.GetOptions(v1alpha1.ApplicationSource{}, true) require.NoError(t, err) assert.Equal(t, "", ver.BinaryPath) assert.Equal(t, "--opt1 val1", ver.BuildOptions) @@ -860,7 +860,7 @@ func TestKustomizeSettings_GetOptions(t *testing.T) { t.Run("VersionExists", func(t *testing.T) { ver, err := settings.GetOptions(v1alpha1.ApplicationSource{ Kustomize: &v1alpha1.ApplicationSourceKustomize{Version: "v2"}, - }) + }, true) require.NoError(t, err) assert.Equal(t, "path_v2", ver.BinaryPath) assert.Equal(t, "", ver.BuildOptions) @@ -869,7 +869,7 @@ func TestKustomizeSettings_GetOptions(t *testing.T) { t.Run("VersionExistsWithBuildOption", func(t *testing.T) { ver, err := settings.GetOptions(v1alpha1.ApplicationSource{ Kustomize: &v1alpha1.ApplicationSourceKustomize{Version: "v3"}, - }) + }, true) require.NoError(t, err) assert.Equal(t, "path_v3", ver.BinaryPath) assert.Equal(t, "--opt2 val2", ver.BuildOptions) diff --git a/util/webhook/webhook_test.go b/util/webhook/webhook_test.go index 9f39ef4c1c24e..6415293a645c5 100644 --- a/util/webhook/webhook_test.go +++ b/util/webhook/webhook_test.go @@ -80,6 +80,7 @@ func NewMockHandlerWithPayloadLimit(reactor *reactorDef, applicationNamespaces [ cacheClient, 1*time.Minute, 1*time.Minute, + 1*time.Minute, 10*time.Second, ), servercache.NewCache(appstate.NewCache(cacheClient, time.Minute), time.Minute, time.Minute, time.Minute), &mocks.ArgoDB{}, maxPayloadSize) }