From 5b5d8a787c663d730db94407a7e56e051813cb0b Mon Sep 17 00:00:00 2001 From: Eron Wright Date: Wed, 7 Aug 2024 20:11:00 -0700 Subject: [PATCH] [pkov2] agent RPC server (#624) ### Proposed changes **Epic Link**: https://github.com/pulumi/pulumi-kubernetes-operator/issues/606 **Demo Video Link**: https://pulumi.slack.com/archives/C07DQSV84DC/p1722636430008649 Implements an agent consisting of two commands: - `init` - fetches a flux source into the given directory, intended for use in an init container. - `serve` - starts an RPC server providing an automation API to perform stack updates over the given workspace. ### Overview The RPC server assumes that the project source code has been checked out to a local working directory, called the "workspace" directory. This generally corresponds to a sub-directory within a git repository, e.g. [examples/random-yaml](https://github.com/pulumi/examples/tree/master/random-yaml). At startup, the server opens the workspace using [auto.NewLocalWorkspace](https://github.com/pulumi/pulumi/blob/5651750bb254f73da5ef0fa503818c5a38755ea8/sdk/go/auto/local_workspace.go#L848). All RPC operations are applied to this same workspace, usually one-at-a-time. Some operations cause state changes, e.g. stack selection, that may affect subsequent operations. Some operations produce `PreconditionFailed` if a stack hasn't been selected. At startup, the server optionally runs `pulumi install` to install dependencies and plugins for the project, based on https://github.com/pulumi/pulumi/pull/16782. Note that PKOv1 has some code to install plugins, now believed to be obsolete (see [discussion](https://github.com/pulumi/pulumi/pull/16782#issuecomment-2259286745)). The supported operations are: - `WhoAmI` - returns current user info. - `Install` - runs `pulumi install` in the workspace. - `SelectStack` - select (and optionally create) a stack, for use in subsequent operations. - `Info` - a summary of the current stack. - `SetAllConfig` - set multiple configuration values on the current stack, based on literals, environment variables, and file references. It is expected that the server's pod would have ConfigMaps and Secrets mounted accordingly. - `Preview` runs the preview operation for the current stack. - `Up` runs the up operation for the current stack. - `Destroy` runs the destroy operation for the current stack. - `Refresh` runs the refresh operation for the current stack. The deployment operations have streaming responses, consisting of a series of engine events and a final result. The agent uses zap for logging, because it supports structured logging, implements `io.Writer` to capture Pulumi console output, and integrates well with grpc-go. ### Follow-ups - [x] Write RPC server tests - [ ] Rename 'init' to 'fetch' for clarity - [ ] lock the workspace during an operation? Or rely on locking within the Pulumi CLI? ### Related issues (optional) Closes #610 #611 --- .../workflows/v2-run-acceptance-tests.yaml | 54 + .goreleaser.yml | 45 +- .vscode/launch.json | 23 + Makefile | 5 +- agent/.gitignore | 2 + agent/Dockerfile | 34 + agent/Makefile | 26 + agent/cmd/init.go | 83 + agent/cmd/root.go | 72 + agent/cmd/serve.go | 192 ++ agent/cmd/version.go | 34 + agent/go.mod | 114 + agent/go.sum | 431 +++ agent/main.go | 22 + agent/pkg/proto/agent.pb.go | 2670 +++++++++++++++++ agent/pkg/proto/agent.proto | 272 ++ agent/pkg/proto/agent_grpc.pb.go | 567 ++++ agent/pkg/server/server.go | 698 +++++ agent/pkg/server/server_test.go | 809 +++++ agent/pkg/server/testdata/foo.txt | 1 + agent/pkg/server/testdata/simple/Pulumi.yaml | 2 + .../server/testdata/uninstallable/Pulumi.yaml | 3 + agent/version/version.go | 3 + go.mod | 1 - go.sum | 2 - 25 files changed, 6160 insertions(+), 5 deletions(-) create mode 100644 .github/workflows/v2-run-acceptance-tests.yaml create mode 100644 agent/.gitignore create mode 100644 agent/Dockerfile create mode 100644 agent/Makefile create mode 100644 agent/cmd/init.go create mode 100644 agent/cmd/root.go create mode 100644 agent/cmd/serve.go create mode 100644 agent/cmd/version.go create mode 100644 agent/go.mod create mode 100644 agent/go.sum create mode 100644 agent/main.go create mode 100644 agent/pkg/proto/agent.pb.go create mode 100644 agent/pkg/proto/agent.proto create mode 100644 agent/pkg/proto/agent_grpc.pb.go create mode 100644 agent/pkg/server/server.go create mode 100644 agent/pkg/server/server_test.go create mode 100644 agent/pkg/server/testdata/foo.txt create mode 100644 agent/pkg/server/testdata/simple/Pulumi.yaml create mode 100644 agent/pkg/server/testdata/uninstallable/Pulumi.yaml create mode 100644 agent/version/version.go diff --git a/.github/workflows/v2-run-acceptance-tests.yaml b/.github/workflows/v2-run-acceptance-tests.yaml new file mode 100644 index 00000000..64b87afd --- /dev/null +++ b/.github/workflows/v2-run-acceptance-tests.yaml @@ -0,0 +1,54 @@ +--- +name: Pulumi Kubernetes Operator PR Builds +on: + pull_request: + branches: + - v2 +env: + PULUMI_ACCESS_TOKEN: ${{ secrets.PULUMI_ACCESS_TOKEN }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} +jobs: + + build: + runs-on: ubuntu-latest + name: Build + steps: + - name: Check out code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Install Go + uses: actions/setup-go@v5 + with: + go-version: 1.22.x + - name: Run GoReleaser + uses: goreleaser/goreleaser-action@v6 + with: + distribution: goreleaser-pro + # 'latest', 'nightly', or a semver + version: '~> v2' + args: release --snapshot --clean --skip=docker + + agent-integration-tests: + runs-on: ubuntu-latest + name: Integration Testing + if: github.event_name == 'repository_dispatch' || github.event.pull_request.head.repo.full_name == github.repository + steps: + - name: Check out code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Install Go + uses: actions/setup-go@v5 + with: + go-version: 1.22.x + - name: Install Pulumi + uses: pulumi/actions@v5 + - name: Run Tests + run: make -C agent test + - name: Upload coverage reports to Codecov + uses: codecov/codecov-action@v4 + with: + file: agent/coverage.out + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} \ No newline at end of file diff --git a/.goreleaser.yml b/.goreleaser.yml index db469a9b..c5863fca 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -1,3 +1,4 @@ +version: 2 project_name: pulumi-kubernetes-operator builds: @@ -18,6 +19,25 @@ builds: main: ./cmd/manager/main.go binary: pulumi-kubernetes-operator + - id: pulumi-kubernetes-agent + ldflags: + - -X github.com/pulumi/pulumi-kubernetes-operator/agent/version.Version={{.Version}} + - -w -extldflags "-static" + flags: + - -a + - -tags + - netgo + goos: + - linux + goarch: + - amd64 + env: + - CGO_ENABLED=0 + - GO111MODULE=on + main: ./main.go + dir: agent + binary: pulumi-kubernetes-agent + archives: - name_template: >- {{ .ProjectName }}_ @@ -44,7 +64,7 @@ release: name_template: "{{.ProjectName}}-v{{.Version}}" dockers: - - + - id: pulumi-kubernetes-operator # GOOS of the built binary that should be used. goos: linux @@ -65,3 +85,26 @@ dockers: - "--label=org.label-schema.name={{ .ProjectName }}" - "--label=org.label-schema.vcs-ref={{ .ShortCommit }}" - "--label=org.label-schema.vcs-url='{{ .GitURL }}'" + + - id: pulumi-kubernetes-agent + # GOOS of the built binary that should be used. + goos: linux + + # GOARCH of the built binary that should be used. + goarch: amd64 + + # Path to the Dockerfile (from the project root). + dockerfile: agent/Dockerfile + + # Templates of the Docker image names. + image_templates: + - "pulumi/pulumi-kubernetes-agent:latest" + - "pulumi/pulumi-kubernetes-agent:{{ .Version }}" + + build_flag_templates: + - "--pull" + - "--label=org.label-schema.build-date={{.Date}}" + - "--label=org.label-schema.name={{ .ProjectName }}" + - "--label=org.label-schema.vcs-ref={{ .ShortCommit }}" + - "--label=org.label-schema.vcs-url='{{ .GitURL }}'" + diff --git a/.vscode/launch.json b/.vscode/launch.json index 9684b178..7e297562 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -18,6 +18,29 @@ "args": [ "--zap-level=debug" ] + }, + { + "name": "Agent", + "type": "go", + "request": "launch", + "mode": "auto", + "program": "agent", + "args": [ + "serve", + "-v=false", + "--workspace=${input:workdir}", + "-s=dev" + ], + "env": { + "AWS_REGION": "us-west-1", + } + } + ], + "inputs": [ + { + "id": "workdir", + "description": "Please provide the Pulumi program directory", + "type": "promptString" } ] } \ No newline at end of file diff --git a/Makefile b/Makefile index d59fbccc..3899d14b 100644 --- a/Makefile +++ b/Makefile @@ -75,4 +75,7 @@ version: dep-tidy: go mod tidy -.PHONY: build build-static codegen generate-crds install-crds generate-k8s test version dep-tidy build-image push-image push-image-latest deploy prep-spec +agent: + cd agent && $(MAKE) agent + +.PHONY: build build-static codegen generate-crds install-crds generate-k8s test version dep-tidy build-image push-image push-image-latest deploy prep-spec agent diff --git a/agent/.gitignore b/agent/.gitignore new file mode 100644 index 00000000..ac623164 --- /dev/null +++ b/agent/.gitignore @@ -0,0 +1,2 @@ +pulumi-kubernetes-agent +coverage.out \ No newline at end of file diff --git a/agent/Dockerfile b/agent/Dockerfile new file mode 100644 index 00000000..72f1f40d --- /dev/null +++ b/agent/Dockerfile @@ -0,0 +1,34 @@ +# Build the agent binary +FROM golang:1.22 AS builder +ARG TARGETOS +ARG TARGETARCH +ARG VERSION + +WORKDIR /workspace +# Copy the Go Modules manifests +COPY go.mod go.mod +COPY go.sum go.sum + +# cache deps before building and copying source so that we don't need to re-download as much +# and so that source changes don't invalidate our downloaded layer +RUN go mod download + +# Copy the go source +COPY main.go main.go +COPY cmd/ cmd/ +COPY pkg/ pkg/ +COPY version/ version/ + +# Build +# the GOARCH has not a default value to allow the binary be built according to the host where the command +# was called. For example, if we call make docker-build in a local env which has the Apple Silicon M1 SO +# the docker BUILDPLATFORM arg will be linux/arm64 when for Apple x86 it will be linux/amd64. Therefore, +# by leaving it empty we can ensure that the container and binary shipped on it will have the same platform. +RUN CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} go build -ldflags "-X github.com/pulumi/pulumi-kubernetes-operator/agent/version.Version=${VERSION}" -a -o agent main.go + +# runtime image +FROM gcr.io/distroless/static-debian12:debug-nonroot + +# install agent binary +WORKDIR / +COPY --from=builder /workspace/agent agent diff --git a/agent/Makefile b/agent/Makefile new file mode 100644 index 00000000..5689e0f7 --- /dev/null +++ b/agent/Makefile @@ -0,0 +1,26 @@ +VERSION ?= $(shell git describe --tags --always --dirty) + +all: protoc agent + +ensure: + go mod tidy + +protoc: + @echo "Generating Go files" + cd pkg/proto && protoc --go_out=. --go_opt=paths=source_relative \ + --go-grpc_out=. --go-grpc_opt=paths=source_relative *.proto + +test: + go test -covermode=atomic -coverprofile=coverage.out -v ./... + +agent: protoc + @echo "Building agent" + go build -o pulumi-kubernetes-agent \ + -ldflags "-X github.com/pulumi/pulumi-kubernetes-operator/agent/version.Version=${VERSION}" \ + github.com/pulumi/pulumi-kubernetes-operator/agent + +image: agent + docker build --build-arg="VERSION=$(VERSION)" -t pulumi/pulumi-kubernetes-agent:latest . + +.PHONY: agent protoc image ensure test + diff --git a/agent/cmd/init.go b/agent/cmd/init.go new file mode 100644 index 00000000..419b758c --- /dev/null +++ b/agent/cmd/init.go @@ -0,0 +1,83 @@ +/* +Copyright © 2024 Pulumi Corporation + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +package cmd + +import ( + "os" + + "github.com/fluxcd/pkg/http/fetch" + "github.com/spf13/cobra" + "go.uber.org/zap" +) + +const ( + DefaultFluxRetries = 3 +) + +var ( + TargetDir string + FluxUrl string + FluxDigest string +) + +// initCmd represents the init command +var initCmd = &cobra.Command{ + Use: "init", + Short: "Initialize a Pulumi workspace", + Long: `Initialize a working directory to contain project sources. + +For Flux sources: + pulumi-kubernetes-agent init --flux-fetch-url URL +`, + Run: func(cmd *cobra.Command, args []string) { + ctx := cmd.Context() + log.Debugw("executing init command", "TargetDir", TargetDir) + + err := os.MkdirAll(TargetDir, 0777) + if err != nil { + log.Errorw("fatal: unable to make target directory", zap.Error(err)) + os.Exit(1) + } + log.Debugw("target directory created", "dir", TargetDir) + + // fetch the configured flux source + if FluxUrl != "" { + // https://github.com/fluxcd/kustomize-controller/blob/a1a33f2adda783dd2a17234f5d8e84caca4e24e2/internal/controller/kustomization_controller.go#L328 + fetcher := fetch.New( + fetch.WithRetries(DefaultFluxRetries), + fetch.WithHostnameOverwrite(os.Getenv("SOURCE_CONTROLLER_LOCALHOST")), + fetch.WithUntar()) + + log.Infow("flux source fetching", "url", FluxUrl, "digest", FluxDigest) + err := fetcher.FetchWithContext(ctx, FluxUrl, FluxDigest, TargetDir) + if err != nil { + log.Errorw("fatal: unable to fetch flux source", zap.Error(err)) + os.Exit(2) + } + log.Infow("flux source fetched", "dir", TargetDir) + } + }, +} + +func init() { + rootCmd.AddCommand(initCmd) + initCmd.Flags().StringVarP(&TargetDir, "target-dir", "t", "", "The target directory to initialize") + initCmd.MarkFlagRequired("target-dir") + + initCmd.Flags().StringVar(&FluxUrl, "flux-url", "", "Flux archive URL") + initCmd.Flags().StringVar(&FluxDigest, "flux-digest", "", "Flux digest") + initCmd.MarkFlagsRequiredTogether("flux-url", "flux-digest") +} diff --git a/agent/cmd/root.go b/agent/cmd/root.go new file mode 100644 index 00000000..4f94a1d4 --- /dev/null +++ b/agent/cmd/root.go @@ -0,0 +1,72 @@ +/* +Copyright © 2024 Pulumi Corporation + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +package cmd + +import ( + "os" + + "github.com/spf13/cobra" + "go.uber.org/zap" +) + +var verbose bool + +// a command-specific logger +var log *zap.SugaredLogger + +// rootCmd represents the base command when called without any subcommands +var rootCmd = &cobra.Command{ + Use: "agent", + Short: "Pulumi Kubernetes Operator Agent", + Long: `Provides tooling and a gRPC service for the Pulumi Kubernetes Operator +to use to perform stack operations.`, + PersistentPreRunE: func(cmd *cobra.Command, args []string) error { + var err error + + // initialize the global logger + zc := zap.NewDevelopmentConfig() + zc.DisableCaller = true + if !verbose { + zc.Level.SetLevel(zap.InfoLevel) + } + zapLog, err := zc.Build() + if err != nil { + return err + } + zap.ReplaceGlobals(zapLog) + + // initialize a command-specific logger + log = zap.L().Named("cmd").Named(cmd.Name()).Sugar() + return nil + }, + PersistentPostRun: func(cmd *cobra.Command, args []string) { + // ignore sync errors: https://github.com/uber-go/zap/pull/347 + _ = zap.L().Sync() + }, +} + +// Execute adds all child commands to the root command and sets flags appropriately. +// This is called by main.main(). It only needs to happen once to the rootCmd. +func Execute() { + err := rootCmd.Execute() + if err != nil { + os.Exit(1) + } +} + +func init() { + rootCmd.PersistentFlags().BoolVarP(&verbose, "verbose", "v", false, "Enable verbose logging") +} diff --git a/agent/cmd/serve.go b/agent/cmd/serve.go new file mode 100644 index 00000000..7690964e --- /dev/null +++ b/agent/cmd/serve.go @@ -0,0 +1,192 @@ +/* +Copyright © 2024 Pulumi Corporation + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +package cmd + +import ( + "context" + "fmt" + "net" + "os" + "os/signal" + "path/filepath" + "syscall" + + grpc_zap "github.com/grpc-ecosystem/go-grpc-middleware/logging/zap" + grpc_ctxtags "github.com/grpc-ecosystem/go-grpc-middleware/tags" + pb "github.com/pulumi/pulumi-kubernetes-operator/agent/pkg/proto" + "github.com/pulumi/pulumi-kubernetes-operator/agent/pkg/server" + "github.com/pulumi/pulumi-kubernetes-operator/agent/version" + "github.com/pulumi/pulumi/sdk/v3/go/auto" + "github.com/spf13/cobra" + "go.uber.org/zap" + "go.uber.org/zap/zapio" + "google.golang.org/grpc" +) + +var ( + WorkDir string + SkipInstall bool + Stack string + Host string + Port int +) + +var rpcLogger *zap.Logger + +// serveCmd represents the serve command +var serveCmd = &cobra.Command{ + Use: "serve", + Short: "Serve the agent RPC service", + Long: `Start the agent gRPC server. +`, + PreRun: func(cmd *cobra.Command, args []string) { + rpcLogger = zap.L().Named("rpc") + grpc_zap.ReplaceGrpcLoggerV2(rpcLogger) + }, + Run: func(cmd *cobra.Command, args []string) { + ctx := cmd.Context() + log.Infow("Pulumi Kubernetes Agent", "version", version.Version) + log.Debugw("executing serve command", "WorkDir", WorkDir) + + // open the workspace using auto api + workspaceOpts := []auto.LocalWorkspaceOption{} + workDir, err := filepath.EvalSymlinks(WorkDir) // resolve the true location of the workspace + if err != nil { + log.Fatalw("unable to resolve the workspace directory", zap.Error(err)) + os.Exit(1) + } + workspaceOpts = append(workspaceOpts, auto.WorkDir(workDir)) + workspace, err := auto.NewLocalWorkspace(ctx, workspaceOpts...) + if err != nil { + log.Fatalw("unable to open the workspace", zap.Error(err)) + os.Exit(1) + } + proj, err := workspace.ProjectSettings(ctx) + if err != nil { + log.Fatalw("unable to get the project settings", zap.Error(err)) + os.Exit(1) + } + log.Infow("opened a local workspace", "workspace", workDir, + "project", proj.Name, "runtime", proj.Runtime.Name()) + + if !SkipInstall { + plog := zap.L().Named("pulumi") + stdout := &zapio.Writer{Log: plog, Level: zap.InfoLevel} + defer stdout.Close() + stderr := &zapio.Writer{Log: plog, Level: zap.WarnLevel} + defer stderr.Close() + opts := &auto.InstallOptions{ + Stdout: stdout, + Stderr: stderr, + } + log.Infow("installing project dependencies") + if err := workspace.Install(ctx, opts); err != nil { + log.Fatalw("installation failed", zap.Error(err)) + os.Exit(1) + } + log.Infow("installation completed") + } + + // Create the automation service + autoServer, err := server.NewServer(ctx, workspace, &server.Options{ + StackName: Stack, + }) + if err != nil { + log.Fatalw("unable to make an automation server", zap.Error(err)) + os.Exit(1) + } + + // Configure the grpc server. + // Apply zap logging and use filters to reduce log verbosity as needed. + address := fmt.Sprintf("%s:%d", Host, Port) + log.Infow("starting the RPC server", "address", address) + serverOpts := []grpc_zap.Option{ + grpc_zap.WithDecider(func(fullMethodName string, err error) bool { + return true + }), + } + decider := func(ctx context.Context, fullMethodName string, servingObject interface{}) bool { + return verbose + } + s := grpc.NewServer( + grpc.ChainUnaryInterceptor( + grpc_ctxtags.UnaryServerInterceptor(grpc_ctxtags.WithFieldExtractor(grpc_ctxtags.CodeGenRequestFieldExtractor)), + grpc_zap.UnaryServerInterceptor(rpcLogger, serverOpts...), + grpc_zap.PayloadUnaryServerInterceptor(rpcLogger, decider), + ), + grpc.ChainStreamInterceptor( + grpc_ctxtags.StreamServerInterceptor(grpc_ctxtags.WithFieldExtractor(grpc_ctxtags.CodeGenRequestFieldExtractor)), + grpc_zap.StreamServerInterceptor(rpcLogger, serverOpts...), + grpc_zap.PayloadStreamServerInterceptor(rpcLogger, decider), + ), + ) + pb.RegisterAutomationServiceServer(s, autoServer) + + // Start the grpc server + lis, err := net.Listen("tcp", address) + if err != nil { + log.Errorw("fatal: unable to start the RPC server", zap.Error(err)) + os.Exit(1) + } + log.Infow("server listening", "address", lis.Addr(), "workspace", workDir) + + cancelCtx := setupSignalHandler() + go func() { + <-cancelCtx.Done() + log.Infow("shutting down the server") + s.GracefulStop() + autoServer.Cancel() + log.Infow("server stopped") + os.Exit(0) + }() + if err := s.Serve(lis); err != nil { + log.Errorw("fatal: server failure", zap.Error(err)) + os.Exit(1) + } + }, +} + +// SetupSignalHandler registers for SIGTERM and SIGINT. A context is returned +// which is canceled on one of these signals. If a second signal is caught, the program +// is terminated with exit code 1. +func setupSignalHandler() context.Context { + ctx, cancel := context.WithCancel(context.Background()) + + c := make(chan os.Signal, 2) + signal.Notify(c, os.Interrupt, syscall.SIGTERM) + go func() { + <-c + cancel() + <-c + os.Exit(1) // second signal. Exit directly. + }() + + return ctx +} + +func init() { + rootCmd.AddCommand(serveCmd) + + serveCmd.Flags().StringVarP(&WorkDir, "workspace", "w", "", "The workspace directory to serve") + serveCmd.MarkFlagRequired("workspace") + + serveCmd.Flags().BoolVar(&SkipInstall, "skip-install", false, "Skip installation of project dependencies") + + serveCmd.Flags().StringVarP(&Stack, "stack", "s", "", "Select (or create) the stack to use") + + serveCmd.Flags().StringVar(&Host, "host", "0.0.0.0", "Server bind address (default: 0.0.0.0)") + serveCmd.Flags().IntVar(&Port, "port", 50051, "Server port (default: 50051)") +} diff --git a/agent/cmd/version.go b/agent/cmd/version.go new file mode 100644 index 00000000..44a6009f --- /dev/null +++ b/agent/cmd/version.go @@ -0,0 +1,34 @@ +/* +Copyright © 2024 Pulumi Corporation + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +package cmd + +import ( + "github.com/pulumi/pulumi-kubernetes-operator/agent/version" + "github.com/spf13/cobra" +) + +// versionCmd represents the version command +var versionCmd = &cobra.Command{ + Use: "version", + Short: "Print version information", + Run: func(cmd *cobra.Command, args []string) { + log.Infow("Pulumi Kubernetes Agent", "version", version.Version) + }, +} + +func init() { + rootCmd.AddCommand(versionCmd) +} diff --git a/agent/go.mod b/agent/go.mod new file mode 100644 index 00000000..b31a6488 --- /dev/null +++ b/agent/go.mod @@ -0,0 +1,114 @@ +module github.com/pulumi/pulumi-kubernetes-operator/agent + +go 1.22.5 + +require ( + github.com/fluxcd/pkg/http/fetch v0.11.0 + github.com/gogo/protobuf v1.3.2 + github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 + github.com/onsi/gomega v1.32.0 + github.com/pulumi/pulumi/sdk/v3 v3.127.1-0.20240801092425-22d28187db0a + github.com/spf13/cobra v1.8.1 + go.uber.org/zap v1.26.0 + google.golang.org/grpc v1.65.0 + google.golang.org/protobuf v1.34.2 + k8s.io/utils v0.0.0-20230726121419-3b25d923346b +) + +// Replace digest lib to master to gather access to BLAKE3. +// xref: https://github.com/opencontainers/go-digest/pull/66 +replace github.com/opencontainers/go-digest => github.com/opencontainers/go-digest v1.0.1-0.20220411205349-bde1400a84be + +require ( + dario.cat/mergo v1.0.0 // indirect + github.com/BurntSushi/toml v1.2.1 // indirect + github.com/Microsoft/go-winio v0.6.1 // indirect + github.com/ProtonMail/go-crypto v1.0.0 // indirect + github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da // indirect + github.com/agext/levenshtein v1.2.3 // indirect + github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect + github.com/atotto/clipboard v0.1.4 // indirect + github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect + github.com/blang/semver v3.5.1+incompatible // indirect + github.com/charmbracelet/bubbles v0.16.1 // indirect + github.com/charmbracelet/bubbletea v0.25.0 // indirect + github.com/charmbracelet/lipgloss v0.7.1 // indirect + github.com/cheggaaa/pb v1.0.29 // indirect + github.com/cloudflare/circl v1.3.7 // indirect + github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 // indirect + github.com/cyphar/filepath-securejoin v0.2.4 // indirect + github.com/djherbis/times v1.5.0 // indirect + github.com/emirpasic/gods v1.18.1 // indirect + github.com/fluxcd/pkg/tar v0.7.0 // indirect + github.com/fsnotify/fsnotify v1.7.0 // indirect + github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect + github.com/go-git/go-billy/v5 v5.5.0 // indirect + github.com/go-git/go-git/v5 v5.12.0 // indirect + github.com/go-logr/logr v1.4.1 // indirect + github.com/golang/glog v1.2.1 // indirect + github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect + github.com/golang/protobuf v1.5.4 // indirect + github.com/google/go-cmp v0.6.0 // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645 // indirect + github.com/hashicorp/errwrap v1.1.0 // indirect + github.com/hashicorp/go-cleanhttp v0.5.2 // indirect + github.com/hashicorp/go-multierror v1.1.1 // indirect + github.com/hashicorp/go-retryablehttp v0.7.5 // indirect + github.com/hashicorp/hcl/v2 v2.17.0 // indirect + github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect + github.com/kevinburke/ssh_config v1.2.0 // indirect + github.com/klauspost/cpuid/v2 v2.2.6 // indirect + github.com/lucasb-eyer/go-colorful v1.2.0 // indirect + github.com/mattn/go-isatty v0.0.19 // indirect + github.com/mattn/go-localereader v0.0.1 // indirect + github.com/mattn/go-runewidth v0.0.15 // indirect + github.com/mitchellh/go-ps v1.0.0 // indirect + github.com/mitchellh/go-wordwrap v1.0.1 // indirect + github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect + github.com/muesli/cancelreader v0.2.2 // indirect + github.com/muesli/reflow v0.3.0 // indirect + github.com/muesli/termenv v0.15.2 // indirect + github.com/nxadm/tail v1.4.11 // indirect + github.com/opencontainers/go-digest v1.0.0 // indirect + github.com/opencontainers/go-digest/blake3 v0.0.0-20231025023718-d50d2fec9c98 // indirect + github.com/opentracing/basictracer-go v1.1.0 // indirect + github.com/opentracing/opentracing-go v1.2.0 // indirect + github.com/pgavlin/fx v0.1.6 // indirect + github.com/pjbgf/sha1cd v0.3.0 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/pkg/term v1.1.0 // indirect + github.com/pulumi/appdash v0.0.0-20231130102222-75f619a67231 // indirect + github.com/pulumi/esc v0.9.1 // indirect + github.com/rivo/uniseg v0.4.4 // indirect + github.com/rogpeppe/go-internal v1.11.0 // indirect + github.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06 // indirect + github.com/santhosh-tekuri/jsonschema/v5 v5.0.0 // indirect + github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect + github.com/skeema/knownhosts v1.2.2 // indirect + github.com/spf13/pflag v1.0.5 // indirect + github.com/texttheater/golang-levenshtein v1.0.1 // indirect + github.com/tweekmonster/luser v0.0.0-20161003172636-3fa38070dbd7 // indirect + github.com/uber/jaeger-client-go v2.30.0+incompatible // indirect + github.com/uber/jaeger-lib v2.4.1+incompatible // indirect + github.com/xanzy/ssh-agent v0.3.3 // indirect + github.com/zclconf/go-cty v1.13.2 // indirect + github.com/zeebo/blake3 v0.2.3 // indirect + go.uber.org/atomic v1.9.0 // indirect + go.uber.org/multierr v1.11.0 // indirect + golang.org/x/crypto v0.24.0 // indirect + golang.org/x/exp v0.0.0-20240604190554-fc45aab8b7f8 // indirect + golang.org/x/mod v0.18.0 // indirect + golang.org/x/net v0.26.0 // indirect + golang.org/x/sync v0.7.0 // indirect + golang.org/x/sys v0.21.0 // indirect + golang.org/x/term v0.21.0 // indirect + golang.org/x/text v0.16.0 // indirect + golang.org/x/tools v0.22.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157 // indirect + gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect + gopkg.in/warnings.v0 v0.1.2 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect + lukechampine.com/frand v1.4.2 // indirect +) diff --git a/agent/go.sum b/agent/go.sum new file mode 100644 index 00000000..321dd0c4 --- /dev/null +++ b/agent/go.sum @@ -0,0 +1,431 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= +dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/toml v1.2.1 h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak= +github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= +github.com/HdrHistogram/hdrhistogram-go v1.1.2 h1:5IcZpTvzydCQeHzK4Ef/D5rrSqwxob0t8PQPMybUNFM= +github.com/HdrHistogram/hdrhistogram-go v1.1.2/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo= +github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= +github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= +github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= +github.com/ProtonMail/go-crypto v1.0.0 h1:LRuvITjQWX+WIfr930YHG2HNfjR1uOfyf5vE0kC2U78= +github.com/ProtonMail/go-crypto v1.0.0/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0= +github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da h1:KjTM2ks9d14ZYCvmHS9iAKVt9AyzRSqNU1qabPih5BY= +github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da/go.mod h1:eHEWzANqSiWQsof+nXEI9bUVUyV6F53Fp89EuCh2EAA= +github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo= +github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= +github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8= +github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4= +github.com/apparentlymart/go-textseg/v13 v13.0.0 h1:Y+KvPE1NYz0xl601PVImeQfFyEy6iT90AvPUL1NNfNw= +github.com/apparentlymart/go-textseg/v13 v13.0.0/go.mod h1:ZK2fH7c4NqDTLtiYLvIkEghdlcqw7yxLeM89kiTRPUo= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= +github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z4= +github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI= +github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k= +github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= +github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= +github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ= +github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= +github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/charmbracelet/bubbles v0.16.1 h1:6uzpAAaT9ZqKssntbvZMlksWHruQLNxg49H5WdeuYSY= +github.com/charmbracelet/bubbles v0.16.1/go.mod h1:2QCp9LFlEsBQMvIYERr7Ww2H2bA7xen1idUDIzm/+Xc= +github.com/charmbracelet/bubbletea v0.25.0 h1:bAfwk7jRz7FKFl9RzlIULPkStffg5k6pNt5dywy4TcM= +github.com/charmbracelet/bubbletea v0.25.0/go.mod h1:EN3QDR1T5ZdWmdfDzYcqOCAps45+QIJbLOBxmVNWNNg= +github.com/charmbracelet/lipgloss v0.7.1 h1:17WMwi7N1b1rVWOjMT+rCh7sQkvDU75B2hbZpc5Kc1E= +github.com/charmbracelet/lipgloss v0.7.1/go.mod h1:yG0k3giv8Qj8edTCbbg6AlQ5e8KNWpFujkNawKNhE2c= +github.com/cheggaaa/pb v1.0.29 h1:FckUN5ngEk2LpvuG0fw1GEFx6LtyY2pWI/Z2QgCnEYo= +github.com/cheggaaa/pb v1.0.29/go.mod h1:W40334L7FMC5JKWldsTWbdGjLo0RxUKK73K+TuPxX30= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA= +github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU= +github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 h1:q2hJAaP1k2wIvVRd/hEHD7lacgqrCPS+k8g1MndzfWY= +github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81/go.mod h1:YynlIjWYF8myEu6sdkwKIvGQq+cOckRm6So2avqoYAk= +github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg= +github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/djherbis/times v1.5.0 h1:79myA211VwPhFTqUk8xehWrsEO+zcIZj0zT8mXPVARU= +github.com/djherbis/times v1.5.0/go.mod h1:5q7FDLvbNg1L/KaBmPcWlVR9NmoKo3+ucqUA3ijQhA0= +github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a h1:mATvB/9r/3gvcejNsXKSkQ6lcIaNec2nyfOdlTBR2lU= +github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM= +github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= +github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= +github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= +github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= +github.com/fluxcd/pkg/http/fetch v0.11.0 h1:ms9M+RlpdmM6/cJxuaw83MQGi3LIutEk2Ck+qWJEpDY= +github.com/fluxcd/pkg/http/fetch v0.11.0/go.mod h1:gSSUEC8xNy+ydOYHEG0aRl8mjTpEY5U0yTksM/zCoQ4= +github.com/fluxcd/pkg/tar v0.7.0 h1:xdg95f4DlzMgd4m+xPRXrX4NLb8P8b5SAqB19sDOLIs= +github.com/fluxcd/pkg/tar v0.7.0/go.mod h1:KLg1zMZF7sEncGA9LEsfkskbCMyLSEgrjBRXqFK++VE= +github.com/fluxcd/pkg/testserver v0.7.0 h1:kNVAn+3bAF2rfR9cT6SxzgEz2o84i+o7zKY3XRKTXmk= +github.com/fluxcd/pkg/testserver v0.7.0/go.mod h1:Ih5IK3Y5G3+a6c77BTqFkdPDCY1Yj1A1W5cXQqkCs9s= +github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= +github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= +github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= +github.com/gliderlabs/ssh v0.3.7 h1:iV3Bqi942d9huXnzEF2Mt+CY9gLu8DNM4Obd+8bODRE= +github.com/gliderlabs/ssh v0.3.7/go.mod h1:zpHEXBstFnQYtGnB8k8kQLol82umzn/2/snG7alWVD8= +github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI= +github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic= +github.com/go-git/go-billy/v5 v5.5.0 h1:yEY4yhzCDuMGSv83oGxiBotRzhwhNr8VZyphhiu+mTU= +github.com/go-git/go-billy/v5 v5.5.0/go.mod h1:hmexnoNsr2SJU1Ju67OaNz5ASJY3+sHgFRpCtpDCKow= +github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4= +github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII= +github.com/go-git/go-git/v5 v5.12.0 h1:7Md+ndsjrzZxbddRDZjF14qK+NN56sy6wkqaVrjZtys= +github.com/go-git/go-git/v5 v5.12.0/go.mod h1:FTM9VKtnI2m65hNI/TenDDDnUf2Q9FHnXYjuz9i5OEY= +github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= +github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= +github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= +github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= +github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/glog v1.2.1 h1:OptwRhECazUx5ix5TTWC3EZhsZEHWcYWY4FQHTIubm4= +github.com/golang/glog v1.2.1/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 h1:yAJXTCF9TqKcTiHJAE8dj7HMvPfh66eeA2JYW7eFpSE= +github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 h1:UH//fgunKIs4JdUbpDl1VZCDaL56wXCB/5+wF6uHfaI= +github.com/grpc-ecosystem/go-grpc-middleware v1.4.0/go.mod h1:g5qyo/la0ALbONm6Vbp88Yd8NsDy6rZz+RcrMPxvld8= +github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645 h1:MJG/KsmcqMwFAkh8mTnAwhyKoB+sTAnY4CACC110tbU= +github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645/go.mod h1:6iZfnjpejD4L/4DwD7NryNaJyCQdzwWwH2MWhCA90Kw= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= +github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= +github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= +github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= +github.com/hashicorp/go-hclog v1.2.2 h1:ihRI7YFwcZdiSD7SIenIhHfQH3OuDvWerAUBZbeQS3M= +github.com/hashicorp/go-hclog v1.2.2/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= +github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= +github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= +github.com/hashicorp/go-retryablehttp v0.7.5 h1:bJj+Pj19UZMIweq/iie+1u5YCdGrnxCT9yvm0e+Nd5M= +github.com/hashicorp/go-retryablehttp v0.7.5/go.mod h1:Jy/gPYAdjqffZ/yFGCFV2doI5wjtH1ewM9u8iYVjtX8= +github.com/hashicorp/hcl/v2 v2.17.0 h1:z1XvSUyXd1HP10U4lrLg5e0JMVz6CPaJvAgxM0KNZVY= +github.com/hashicorp/hcl/v2 v2.17.0/go.mod h1:gJyW2PTShkJqQBKpAmPO3yxMxIuoXkOF2TpqXzrQyx4= +github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= +github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= +github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= +github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4= +github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= +github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/cpuid/v2 v2.0.12/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c= +github.com/klauspost/cpuid/v2 v2.2.6 h1:ndNyv040zDGIDh8thGkXYjnFtiN02M1PVVF+JE/48xc= +github.com/klauspost/cpuid/v2 v2.2.6/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= +github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= +github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40= +github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= +github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= +github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= +github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-localereader v0.0.1 h1:ygSAOl7ZXTx4RdPYinUpg6W99U8jWvWi9Ye2JC/oIi4= +github.com/mattn/go-localereader v0.0.1/go.mod h1:8fBrzywKY7BI3czFoHkuzRoWE9C+EiG4R1k4Cjx5p88= +github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= +github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= +github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= +github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/mitchellh/go-ps v1.0.0 h1:i6ampVEEF4wQFF+bkYfwYgY+F/uYJDktmvLPf7qIgjc= +github.com/mitchellh/go-ps v1.0.0/go.mod h1:J4lOc8z8yJs6vUwklHw2XEIiT4z4C40KtWVN3nvg8Pg= +github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0= +github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0= +github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 h1:ZK8zHtRHOkbHy6Mmr5D264iyp3TiX5OmNcI5cIARiQI= +github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6/go.mod h1:CJlz5H+gyd6CUWT45Oy4q24RdLyn7Md9Vj2/ldJBSIo= +github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELUXHmA= +github.com/muesli/cancelreader v0.2.2/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo= +github.com/muesli/reflow v0.3.0 h1:IFsN6K9NfGtjeggFP+68I4chLZV2yIKsXJFNZ+eWh6s= +github.com/muesli/reflow v0.3.0/go.mod h1:pbwTDkVPibjO2kyvBQRBxTWEEGDGq0FlB1BIKtnHY/8= +github.com/muesli/termenv v0.15.2 h1:GohcuySI0QmI3wN8Ok9PtKGkgkFIk7y6Vpb5PvrY+Wo= +github.com/muesli/termenv v0.15.2/go.mod h1:Epx+iuz8sNs7mNKhxzH4fWXGNpZwUaJKRS1noLXviQ8= +github.com/nxadm/tail v1.4.11 h1:8feyoE3OzPrcshW5/MJ4sGESc5cqmGkGCWlco4l0bqY= +github.com/nxadm/tail v1.4.11/go.mod h1:OTaG3NK980DZzxbRq6lEuzgU+mug70nY11sMd4JXXHc= +github.com/onsi/ginkgo/v2 v2.15.0 h1:79HwNRBAZHOEwrczrgSOPy+eFTTlIGELKy5as+ClttY= +github.com/onsi/ginkgo/v2 v2.15.0/go.mod h1:HlxMHtYF57y6Dpf+mc5529KKmSq9h2FpCF+/ZkwUxKM= +github.com/onsi/gomega v1.32.0 h1:JRYU78fJ1LPxlckP6Txi/EYqJvjtMrDC04/MM5XRHPk= +github.com/onsi/gomega v1.32.0/go.mod h1:a4x4gW6Pz2yK1MAmvluYme5lvYTn61afQ2ETw/8n4Lg= +github.com/opencontainers/go-digest v1.0.1-0.20220411205349-bde1400a84be h1:f2PlhC9pm5sqpBZFvnAoKj+KzXRzbjFMA+TqXfJdgho= +github.com/opencontainers/go-digest v1.0.1-0.20220411205349-bde1400a84be/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= +github.com/opencontainers/go-digest/blake3 v0.0.0-20231025023718-d50d2fec9c98 h1:LTxrNWOPwquJy9Cu3oz6QHJIO5M5gNyOZtSybXdyLA4= +github.com/opencontainers/go-digest/blake3 v0.0.0-20231025023718-d50d2fec9c98/go.mod h1:kqQaIc6bZstKgnGpL7GD5dWoLKbA6mH1Y9ULjGImBnM= +github.com/opentracing/basictracer-go v1.1.0 h1:Oa1fTSBvAl8pa3U+IJYqrKm0NALwH9OsgwOqDv4xJW0= +github.com/opentracing/basictracer-go v1.1.0/go.mod h1:V2HZueSJEp879yv285Aap1BS69fQMD+MNP1mRs6mBQc= +github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= +github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= +github.com/pgavlin/fx v0.1.6 h1:r9jEg69DhNoCd3Xh0+5mIbdbS3PqWrVWujkY76MFRTU= +github.com/pgavlin/fx v0.1.6/go.mod h1:KWZJ6fqBBSh8GxHYqwYCf3rYE7Gp2p0N8tJp8xv9u9M= +github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4= +github.com/pjbgf/sha1cd v0.3.0/go.mod h1:nZ1rrWOcGJ5uZgEEVL1VUM9iRQiZvWdbZjkKyFzPPsI= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/term v1.1.0 h1:xIAAdCMh3QIAy+5FrE8Ad8XoDhEU4ufwbaSozViP9kk= +github.com/pkg/term v1.1.0/go.mod h1:E25nymQcrSllhX42Ok8MRm1+hyBdHY0dCeiKZ9jpNGw= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/pulumi/appdash v0.0.0-20231130102222-75f619a67231 h1:vkHw5I/plNdTr435cARxCW6q9gc0S/Yxz7Mkd38pOb0= +github.com/pulumi/appdash v0.0.0-20231130102222-75f619a67231/go.mod h1:murToZ2N9hNJzewjHBgfFdXhZKjY3z5cYC1VXk+lbFE= +github.com/pulumi/esc v0.9.1 h1:HH5eEv8sgyxSpY5a8yePyqFXzA8cvBvapfH8457+mIs= +github.com/pulumi/esc v0.9.1/go.mod h1:oEJ6bOsjYlQUpjf70GiX+CXn3VBmpwFDxUTlmtUN84c= +github.com/pulumi/pulumi/sdk/v3 v3.127.1-0.20240801092425-22d28187db0a h1:NKot70gaO4Rjuodf3gAn//SR6dpyad6LSUfuvjZWvao= +github.com/pulumi/pulumi/sdk/v3 v3.127.1-0.20240801092425-22d28187db0a/go.mod h1:p1U24en3zt51agx+WlNboSOV8eLlPWYAkxMzVEXKbnY= +github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis= +github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= +github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= +github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06 h1:OkMGxebDjyw0ULyrTYWeN0UNCCkmCWfjPnIA2W6oviI= +github.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06/go.mod h1:+ePHsJ1keEjQtpvf9HHw0f4ZeJ0TLRsxhunSI2hYJSs= +github.com/santhosh-tekuri/jsonschema/v5 v5.0.0 h1:TToq11gyfNlrMFZiYujSekIsPd9AmsA2Bj/iv+s4JHE= +github.com/santhosh-tekuri/jsonschema/v5 v5.0.0/go.mod h1:FKdcjfQW6rpZSnxxUvEA5H/cDPdvJ/SZJQLWWXWGrZ0= +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/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/skeema/knownhosts v1.2.2 h1:Iug2P4fLmDw9f41PB6thxUkNUkJzB5i+1/exaj40L3A= +github.com/skeema/knownhosts v1.2.2/go.mod h1:xYbVRSPxqBZFrdmDyMmsOs+uX1UZC3nTN3ThzgDxUwo= +github.com/spf13/cast v1.4.1 h1:s0hze+J0196ZfEMTs80N7UlFt0BDuQ7Q+JDnHiMWKdA= +github.com/spf13/cast v1.4.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= +github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/texttheater/golang-levenshtein v1.0.1 h1:+cRNoVrfiwufQPhoMzB6N0Yf/Mqajr6t1lOv8GyGE2U= +github.com/texttheater/golang-levenshtein v1.0.1/go.mod h1:PYAKrbF5sAiq9wd+H82hs7gNaen0CplQ9uvm6+enD/8= +github.com/tweekmonster/luser v0.0.0-20161003172636-3fa38070dbd7 h1:X9dsIWPuuEJlPX//UmRKophhOKCGXc46RVIGuttks68= +github.com/tweekmonster/luser v0.0.0-20161003172636-3fa38070dbd7/go.mod h1:UxoP3EypF8JfGEjAII8jx1q8rQyDnX8qdTCs/UQBVIE= +github.com/uber/jaeger-client-go v2.30.0+incompatible h1:D6wyKGCecFaSRUpo8lCVbaOOb6ThwMmTEbhRwtKR97o= +github.com/uber/jaeger-client-go v2.30.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= +github.com/uber/jaeger-lib v2.4.1+incompatible h1:td4jdvLcExb4cBISKIpHuGoVXh+dVKhn2Um6rjCsSsg= +github.com/uber/jaeger-lib v2.4.1+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= +github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= +github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +github.com/zclconf/go-cty v1.13.2 h1:4GvrUxe/QUDYuJKAav4EYqdM47/kZa672LwmXFmEKT0= +github.com/zclconf/go-cty v1.13.2/go.mod h1:YKQzy/7pZ7iq2jNFzy5go57xdxdWoLLpaEp4u238AE0= +github.com/zeebo/assert v1.1.0 h1:hU1L1vLTHsnO8x8c9KAR5GmM5QscxHg5RNU5z5qbUWY= +github.com/zeebo/assert v1.1.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0= +github.com/zeebo/blake3 v0.2.3 h1:TFoLXsjeXqRNFxSbk35Dk4YtszE/MQQGK10BH4ptoTg= +github.com/zeebo/blake3 v0.2.3/go.mod h1:mjJjZpnsyIVtVgTOSpJ9vmRE4wgDeyt2HU3qXvvKCaQ= +github.com/zeebo/pcg v1.0.1 h1:lyqfGeWiv4ahac6ttHs+I5hwtH/+1mrhlCtVNQM2kHo= +github.com/zeebo/pcg v1.0.1/go.mod h1:09F0S9iiKrwn9rlI5yjLkmrug154/YRW6KnnXVDM/l4= +go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= +go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= +go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= +go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo= +go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= +go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= +go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +go.uber.org/zap v1.18.1/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= +go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= +go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= +golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= +golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI= +golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20240604190554-fc45aab8b7f8 h1:LoYXNGAShUG3m/ehNk4iFctuhGX/+R1ZpfJ4/ia80JM= +golang.org/x/exp v0.0.0-20240604190554-fc45aab8b7f8/go.mod h1:jj3sYF3dwk5D+ghuXyeI3r5MFf+NT2An6/9dOA95KSI= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0= +golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200421231249-e086a090c8fd/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= +golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= +golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= +golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= +golang.org/x/term v0.21.0 h1:WVXCp+/EBEHOj53Rvu+7KiT/iElMrO8ACK16SMZ3jaA= +golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= +golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA= +golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157 h1:Zy9XzmMEflZ/MAaA7vNcoebnRAld7FsPW1EeBB7V0m8= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157/go.mod h1:EfXuqaE1J41VCDicxHzUDm+8rk+7ZdXzHV0IhO/I6s0= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= +google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= +google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= +google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= +google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= +gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +k8s.io/utils v0.0.0-20230726121419-3b25d923346b h1:sgn3ZU783SCgtaSJjpcVVlRqd6GSnlTLKgpAAttJvpI= +k8s.io/utils v0.0.0-20230726121419-3b25d923346b/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +lukechampine.com/frand v1.4.2 h1:RzFIpOvkMXuPMBb9maa4ND4wjBn71E1Jpf8BzJHMaVw= +lukechampine.com/frand v1.4.2/go.mod h1:4S/TM2ZgrKejMcKMbeLjISpJMO+/eZ1zu3vYX9dtj3s= +pgregory.net/rapid v0.5.5 h1:jkgx1TjbQPD/feRoK+S/mXw9e1uj6WilpHrXJowi6oA= +pgregory.net/rapid v0.5.5/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04= diff --git a/agent/main.go b/agent/main.go new file mode 100644 index 00000000..770b2a6f --- /dev/null +++ b/agent/main.go @@ -0,0 +1,22 @@ +/* +Copyright © 2024 Pulumi Corporation + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +package main + +import "github.com/pulumi/pulumi-kubernetes-operator/agent/cmd" + +func main() { + cmd.Execute() +} diff --git a/agent/pkg/proto/agent.pb.go b/agent/pkg/proto/agent.pb.go new file mode 100644 index 00000000..702930b4 --- /dev/null +++ b/agent/pkg/proto/agent.pb.go @@ -0,0 +1,2670 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.34.2 +// protoc v5.27.1 +// source: agent.proto + +package proto + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + structpb "google.golang.org/protobuf/types/known/structpb" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type WhoAmIRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *WhoAmIRequest) Reset() { + *x = WhoAmIRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_agent_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *WhoAmIRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*WhoAmIRequest) ProtoMessage() {} + +func (x *WhoAmIRequest) ProtoReflect() protoreflect.Message { + mi := &file_agent_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use WhoAmIRequest.ProtoReflect.Descriptor instead. +func (*WhoAmIRequest) Descriptor() ([]byte, []int) { + return file_agent_proto_rawDescGZIP(), []int{0} +} + +// WhoAmIResult contains detailed information about the currently logged-in +// Pulumi identity. +type WhoAmIResult struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + User string `protobuf:"bytes,1,opt,name=user,proto3" json:"user,omitempty"` + Organizations []string `protobuf:"bytes,2,rep,name=organizations,proto3" json:"organizations,omitempty"` + Url string `protobuf:"bytes,3,opt,name=url,proto3" json:"url,omitempty"` +} + +func (x *WhoAmIResult) Reset() { + *x = WhoAmIResult{} + if protoimpl.UnsafeEnabled { + mi := &file_agent_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *WhoAmIResult) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*WhoAmIResult) ProtoMessage() {} + +func (x *WhoAmIResult) ProtoReflect() protoreflect.Message { + mi := &file_agent_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use WhoAmIResult.ProtoReflect.Descriptor instead. +func (*WhoAmIResult) Descriptor() ([]byte, []int) { + return file_agent_proto_rawDescGZIP(), []int{1} +} + +func (x *WhoAmIResult) GetUser() string { + if x != nil { + return x.User + } + return "" +} + +func (x *WhoAmIResult) GetOrganizations() []string { + if x != nil { + return x.Organizations + } + return nil +} + +func (x *WhoAmIResult) GetUrl() string { + if x != nil { + return x.Url + } + return "" +} + +type SelectStackRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + StackName string `protobuf:"bytes,1,opt,name=stack_name,json=stackName,proto3" json:"stack_name,omitempty"` + Create *bool `protobuf:"varint,2,opt,name=create,proto3,oneof" json:"create,omitempty"` + SecretsProvider *string `protobuf:"bytes,3,opt,name=secrets_provider,json=secretsProvider,proto3,oneof" json:"secrets_provider,omitempty"` +} + +func (x *SelectStackRequest) Reset() { + *x = SelectStackRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_agent_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SelectStackRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SelectStackRequest) ProtoMessage() {} + +func (x *SelectStackRequest) ProtoReflect() protoreflect.Message { + mi := &file_agent_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SelectStackRequest.ProtoReflect.Descriptor instead. +func (*SelectStackRequest) Descriptor() ([]byte, []int) { + return file_agent_proto_rawDescGZIP(), []int{2} +} + +func (x *SelectStackRequest) GetStackName() string { + if x != nil { + return x.StackName + } + return "" +} + +func (x *SelectStackRequest) GetCreate() bool { + if x != nil && x.Create != nil { + return *x.Create + } + return false +} + +func (x *SelectStackRequest) GetSecretsProvider() string { + if x != nil && x.SecretsProvider != nil { + return *x.SecretsProvider + } + return "" +} + +type SelectStackResult struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Summary *StackSummary `protobuf:"bytes,1,opt,name=summary,proto3" json:"summary,omitempty"` +} + +func (x *SelectStackResult) Reset() { + *x = SelectStackResult{} + if protoimpl.UnsafeEnabled { + mi := &file_agent_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SelectStackResult) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SelectStackResult) ProtoMessage() {} + +func (x *SelectStackResult) ProtoReflect() protoreflect.Message { + mi := &file_agent_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SelectStackResult.ProtoReflect.Descriptor instead. +func (*SelectStackResult) Descriptor() ([]byte, []int) { + return file_agent_proto_rawDescGZIP(), []int{3} +} + +func (x *SelectStackResult) GetSummary() *StackSummary { + if x != nil { + return x.Summary + } + return nil +} + +type InfoRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *InfoRequest) Reset() { + *x = InfoRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_agent_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *InfoRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*InfoRequest) ProtoMessage() {} + +func (x *InfoRequest) ProtoReflect() protoreflect.Message { + mi := &file_agent_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use InfoRequest.ProtoReflect.Descriptor instead. +func (*InfoRequest) Descriptor() ([]byte, []int) { + return file_agent_proto_rawDescGZIP(), []int{4} +} + +type InfoResult struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Summary *StackSummary `protobuf:"bytes,1,opt,name=summary,proto3" json:"summary,omitempty"` +} + +func (x *InfoResult) Reset() { + *x = InfoResult{} + if protoimpl.UnsafeEnabled { + mi := &file_agent_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *InfoResult) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*InfoResult) ProtoMessage() {} + +func (x *InfoResult) ProtoReflect() protoreflect.Message { + mi := &file_agent_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use InfoResult.ProtoReflect.Descriptor instead. +func (*InfoResult) Descriptor() ([]byte, []int) { + return file_agent_proto_rawDescGZIP(), []int{5} +} + +func (x *InfoResult) GetSummary() *StackSummary { + if x != nil { + return x.Summary + } + return nil +} + +// StackSummary is a description of a stack and its current status. +type StackSummary struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + LastUpdate *timestamppb.Timestamp `protobuf:"bytes,2,opt,name=last_update,json=lastUpdate,proto3" json:"last_update,omitempty"` + UpdateInProgress bool `protobuf:"varint,3,opt,name=update_in_progress,json=updateInProgress,proto3" json:"update_in_progress,omitempty"` + ResourceCount *int32 `protobuf:"varint,4,opt,name=resource_count,json=resourceCount,proto3,oneof" json:"resource_count,omitempty"` + Url *string `protobuf:"bytes,5,opt,name=url,proto3,oneof" json:"url,omitempty"` +} + +func (x *StackSummary) Reset() { + *x = StackSummary{} + if protoimpl.UnsafeEnabled { + mi := &file_agent_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *StackSummary) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*StackSummary) ProtoMessage() {} + +func (x *StackSummary) ProtoReflect() protoreflect.Message { + mi := &file_agent_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use StackSummary.ProtoReflect.Descriptor instead. +func (*StackSummary) Descriptor() ([]byte, []int) { + return file_agent_proto_rawDescGZIP(), []int{6} +} + +func (x *StackSummary) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *StackSummary) GetLastUpdate() *timestamppb.Timestamp { + if x != nil { + return x.LastUpdate + } + return nil +} + +func (x *StackSummary) GetUpdateInProgress() bool { + if x != nil { + return x.UpdateInProgress + } + return false +} + +func (x *StackSummary) GetResourceCount() int32 { + if x != nil && x.ResourceCount != nil { + return *x.ResourceCount + } + return 0 +} + +func (x *StackSummary) GetUrl() string { + if x != nil && x.Url != nil { + return *x.Url + } + return "" +} + +type SetAllConfigRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Path *bool `protobuf:"varint,1,opt,name=path,proto3,oneof" json:"path,omitempty"` // Parse the keys as paths in a map or list rather than raw strings + Config map[string]*ConfigValue `protobuf:"bytes,2,rep,name=config,proto3" json:"config,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` // a map of ConfigValue used by Pulumi programs +} + +func (x *SetAllConfigRequest) Reset() { + *x = SetAllConfigRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_agent_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SetAllConfigRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SetAllConfigRequest) ProtoMessage() {} + +func (x *SetAllConfigRequest) ProtoReflect() protoreflect.Message { + mi := &file_agent_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SetAllConfigRequest.ProtoReflect.Descriptor instead. +func (*SetAllConfigRequest) Descriptor() ([]byte, []int) { + return file_agent_proto_rawDescGZIP(), []int{7} +} + +func (x *SetAllConfigRequest) GetPath() bool { + if x != nil && x.Path != nil { + return *x.Path + } + return false +} + +func (x *SetAllConfigRequest) GetConfig() map[string]*ConfigValue { + if x != nil { + return x.Config + } + return nil +} + +type ConfigValue struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Types that are assignable to V: + // + // *ConfigValue_Value + // *ConfigValue_ValueFrom + V isConfigValue_V `protobuf_oneof:"v"` + Secret *bool `protobuf:"varint,3,opt,name=secret,proto3,oneof" json:"secret,omitempty"` +} + +func (x *ConfigValue) Reset() { + *x = ConfigValue{} + if protoimpl.UnsafeEnabled { + mi := &file_agent_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ConfigValue) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ConfigValue) ProtoMessage() {} + +func (x *ConfigValue) ProtoReflect() protoreflect.Message { + mi := &file_agent_proto_msgTypes[8] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ConfigValue.ProtoReflect.Descriptor instead. +func (*ConfigValue) Descriptor() ([]byte, []int) { + return file_agent_proto_rawDescGZIP(), []int{8} +} + +func (m *ConfigValue) GetV() isConfigValue_V { + if m != nil { + return m.V + } + return nil +} + +func (x *ConfigValue) GetValue() *structpb.Value { + if x, ok := x.GetV().(*ConfigValue_Value); ok { + return x.Value + } + return nil +} + +func (x *ConfigValue) GetValueFrom() *ConfigValueFrom { + if x, ok := x.GetV().(*ConfigValue_ValueFrom); ok { + return x.ValueFrom + } + return nil +} + +func (x *ConfigValue) GetSecret() bool { + if x != nil && x.Secret != nil { + return *x.Secret + } + return false +} + +type isConfigValue_V interface { + isConfigValue_V() +} + +type ConfigValue_Value struct { + Value *structpb.Value `protobuf:"bytes,1,opt,name=value,proto3,oneof"` +} + +type ConfigValue_ValueFrom struct { + ValueFrom *ConfigValueFrom `protobuf:"bytes,2,opt,name=value_from,json=valueFrom,proto3,oneof"` +} + +func (*ConfigValue_Value) isConfigValue_V() {} + +func (*ConfigValue_ValueFrom) isConfigValue_V() {} + +type ConfigValueFrom struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Types that are assignable to F: + // + // *ConfigValueFrom_Env + // *ConfigValueFrom_Path + F isConfigValueFrom_F `protobuf_oneof:"f"` +} + +func (x *ConfigValueFrom) Reset() { + *x = ConfigValueFrom{} + if protoimpl.UnsafeEnabled { + mi := &file_agent_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ConfigValueFrom) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ConfigValueFrom) ProtoMessage() {} + +func (x *ConfigValueFrom) ProtoReflect() protoreflect.Message { + mi := &file_agent_proto_msgTypes[9] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ConfigValueFrom.ProtoReflect.Descriptor instead. +func (*ConfigValueFrom) Descriptor() ([]byte, []int) { + return file_agent_proto_rawDescGZIP(), []int{9} +} + +func (m *ConfigValueFrom) GetF() isConfigValueFrom_F { + if m != nil { + return m.F + } + return nil +} + +func (x *ConfigValueFrom) GetEnv() string { + if x, ok := x.GetF().(*ConfigValueFrom_Env); ok { + return x.Env + } + return "" +} + +func (x *ConfigValueFrom) GetPath() string { + if x, ok := x.GetF().(*ConfigValueFrom_Path); ok { + return x.Path + } + return "" +} + +type isConfigValueFrom_F interface { + isConfigValueFrom_F() +} + +type ConfigValueFrom_Env struct { + Env string `protobuf:"bytes,1,opt,name=env,proto3,oneof"` // the name of an environment variable to read +} + +type ConfigValueFrom_Path struct { + Path string `protobuf:"bytes,2,opt,name=path,proto3,oneof"` // the path to a file to read +} + +func (*ConfigValueFrom_Env) isConfigValueFrom_F() {} + +func (*ConfigValueFrom_Path) isConfigValueFrom_F() {} + +type SetAllConfigResult struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *SetAllConfigResult) Reset() { + *x = SetAllConfigResult{} + if protoimpl.UnsafeEnabled { + mi := &file_agent_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SetAllConfigResult) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SetAllConfigResult) ProtoMessage() {} + +func (x *SetAllConfigResult) ProtoReflect() protoreflect.Message { + mi := &file_agent_proto_msgTypes[10] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SetAllConfigResult.ProtoReflect.Descriptor instead. +func (*SetAllConfigResult) Descriptor() ([]byte, []int) { + return file_agent_proto_rawDescGZIP(), []int{10} +} + +type InstallRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *InstallRequest) Reset() { + *x = InstallRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_agent_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *InstallRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*InstallRequest) ProtoMessage() {} + +func (x *InstallRequest) ProtoReflect() protoreflect.Message { + mi := &file_agent_proto_msgTypes[11] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use InstallRequest.ProtoReflect.Descriptor instead. +func (*InstallRequest) Descriptor() ([]byte, []int) { + return file_agent_proto_rawDescGZIP(), []int{11} +} + +type InstallResult struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *InstallResult) Reset() { + *x = InstallResult{} + if protoimpl.UnsafeEnabled { + mi := &file_agent_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *InstallResult) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*InstallResult) ProtoMessage() {} + +func (x *InstallResult) ProtoReflect() protoreflect.Message { + mi := &file_agent_proto_msgTypes[12] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use InstallResult.ProtoReflect.Descriptor instead. +func (*InstallResult) Descriptor() ([]byte, []int) { + return file_agent_proto_rawDescGZIP(), []int{12} +} + +type RefreshRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // parallel is the number of resource operations to run in parallel at once + // (1 for no parallelism). Defaults to unbounded. (default 2147483647) + Parallel *int32 `protobuf:"varint,1,opt,name=parallel,proto3,oneof" json:"parallel,omitempty"` + // message (optional) to associate with the preview operation + Message *string `protobuf:"bytes,2,opt,name=message,proto3,oneof" json:"message,omitempty"` + // Return an error if any changes occur during this refresh + ExpectNoChanges *bool `protobuf:"varint,3,opt,name=expect_no_changes,json=expectNoChanges,proto3,oneof" json:"expect_no_changes,omitempty"` + // Specify an exclusive list of resource URNs to refresh + Target []string `protobuf:"bytes,4,rep,name=target,proto3" json:"target,omitempty"` +} + +func (x *RefreshRequest) Reset() { + *x = RefreshRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_agent_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RefreshRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RefreshRequest) ProtoMessage() {} + +func (x *RefreshRequest) ProtoReflect() protoreflect.Message { + mi := &file_agent_proto_msgTypes[13] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RefreshRequest.ProtoReflect.Descriptor instead. +func (*RefreshRequest) Descriptor() ([]byte, []int) { + return file_agent_proto_rawDescGZIP(), []int{13} +} + +func (x *RefreshRequest) GetParallel() int32 { + if x != nil && x.Parallel != nil { + return *x.Parallel + } + return 0 +} + +func (x *RefreshRequest) GetMessage() string { + if x != nil && x.Message != nil { + return *x.Message + } + return "" +} + +func (x *RefreshRequest) GetExpectNoChanges() bool { + if x != nil && x.ExpectNoChanges != nil { + return *x.ExpectNoChanges + } + return false +} + +func (x *RefreshRequest) GetTarget() []string { + if x != nil { + return x.Target + } + return nil +} + +type RefreshStream struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Types that are assignable to Response: + // + // *RefreshStream_Event + // *RefreshStream_Result + Response isRefreshStream_Response `protobuf_oneof:"response"` +} + +func (x *RefreshStream) Reset() { + *x = RefreshStream{} + if protoimpl.UnsafeEnabled { + mi := &file_agent_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RefreshStream) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RefreshStream) ProtoMessage() {} + +func (x *RefreshStream) ProtoReflect() protoreflect.Message { + mi := &file_agent_proto_msgTypes[14] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RefreshStream.ProtoReflect.Descriptor instead. +func (*RefreshStream) Descriptor() ([]byte, []int) { + return file_agent_proto_rawDescGZIP(), []int{14} +} + +func (m *RefreshStream) GetResponse() isRefreshStream_Response { + if m != nil { + return m.Response + } + return nil +} + +func (x *RefreshStream) GetEvent() *structpb.Struct { + if x, ok := x.GetResponse().(*RefreshStream_Event); ok { + return x.Event + } + return nil +} + +func (x *RefreshStream) GetResult() *RefreshResult { + if x, ok := x.GetResponse().(*RefreshStream_Result); ok { + return x.Result + } + return nil +} + +type isRefreshStream_Response interface { + isRefreshStream_Response() +} + +type RefreshStream_Event struct { + // describes a Pulumi engine event, such as a change to a resource or + // diagnostic message. + Event *structpb.Struct `protobuf:"bytes,1,opt,name=event,proto3,oneof"` +} + +type RefreshStream_Result struct { + Result *RefreshResult `protobuf:"bytes,2,opt,name=result,proto3,oneof"` +} + +func (*RefreshStream_Event) isRefreshStream_Response() {} + +func (*RefreshStream_Result) isRefreshStream_Response() {} + +type RefreshResult struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Stdout string `protobuf:"bytes,1,opt,name=stdout,proto3" json:"stdout,omitempty"` + Stderr string `protobuf:"bytes,2,opt,name=stderr,proto3" json:"stderr,omitempty"` + Summary *UpdateSummary `protobuf:"bytes,3,opt,name=summary,proto3" json:"summary,omitempty"` + Permalink *string `protobuf:"bytes,4,opt,name=permalink,proto3,oneof" json:"permalink,omitempty"` +} + +func (x *RefreshResult) Reset() { + *x = RefreshResult{} + if protoimpl.UnsafeEnabled { + mi := &file_agent_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RefreshResult) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RefreshResult) ProtoMessage() {} + +func (x *RefreshResult) ProtoReflect() protoreflect.Message { + mi := &file_agent_proto_msgTypes[15] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RefreshResult.ProtoReflect.Descriptor instead. +func (*RefreshResult) Descriptor() ([]byte, []int) { + return file_agent_proto_rawDescGZIP(), []int{15} +} + +func (x *RefreshResult) GetStdout() string { + if x != nil { + return x.Stdout + } + return "" +} + +func (x *RefreshResult) GetStderr() string { + if x != nil { + return x.Stderr + } + return "" +} + +func (x *RefreshResult) GetSummary() *UpdateSummary { + if x != nil { + return x.Summary + } + return nil +} + +func (x *RefreshResult) GetPermalink() string { + if x != nil && x.Permalink != nil { + return *x.Permalink + } + return "" +} + +type PreviewRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Parallel is the number of resource operations to run in parallel at once + // (1 for no parallelism). Defaults to unbounded. (default 2147483647) + Parallel *int32 `protobuf:"varint,1,opt,name=parallel,proto3,oneof" json:"parallel,omitempty"` + // Message (optional) to associate with the preview operation + Message *string `protobuf:"bytes,2,opt,name=message,proto3,oneof" json:"message,omitempty"` + // Return an error if any changes occur during this preview + ExpectNoChanges *bool `protobuf:"varint,3,opt,name=expect_no_changes,json=expectNoChanges,proto3,oneof" json:"expect_no_changes,omitempty"` + // Specify resources to replace + Replace []string `protobuf:"bytes,4,rep,name=replace,proto3" json:"replace,omitempty"` + // Specify an exclusive list of resource URNs to update + Target []string `protobuf:"bytes,5,rep,name=target,proto3" json:"target,omitempty"` + // Allows updating of dependent targets discovered but not specified in the + // Target list + TargetDependents *bool `protobuf:"varint,6,opt,name=target_dependents,json=targetDependents,proto3,oneof" json:"target_dependents,omitempty"` + // Run one or more policy packs as part of this update + PolicyPack []*PolicyPack `protobuf:"bytes,7,rep,name=policy_pack,json=policyPack,proto3" json:"policy_pack,omitempty"` + // Refresh will run a refresh before the preview. + Refresh *bool `protobuf:"varint,8,opt,name=refresh,proto3,oneof" json:"refresh,omitempty"` +} + +func (x *PreviewRequest) Reset() { + *x = PreviewRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_agent_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PreviewRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PreviewRequest) ProtoMessage() {} + +func (x *PreviewRequest) ProtoReflect() protoreflect.Message { + mi := &file_agent_proto_msgTypes[16] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PreviewRequest.ProtoReflect.Descriptor instead. +func (*PreviewRequest) Descriptor() ([]byte, []int) { + return file_agent_proto_rawDescGZIP(), []int{16} +} + +func (x *PreviewRequest) GetParallel() int32 { + if x != nil && x.Parallel != nil { + return *x.Parallel + } + return 0 +} + +func (x *PreviewRequest) GetMessage() string { + if x != nil && x.Message != nil { + return *x.Message + } + return "" +} + +func (x *PreviewRequest) GetExpectNoChanges() bool { + if x != nil && x.ExpectNoChanges != nil { + return *x.ExpectNoChanges + } + return false +} + +func (x *PreviewRequest) GetReplace() []string { + if x != nil { + return x.Replace + } + return nil +} + +func (x *PreviewRequest) GetTarget() []string { + if x != nil { + return x.Target + } + return nil +} + +func (x *PreviewRequest) GetTargetDependents() bool { + if x != nil && x.TargetDependents != nil { + return *x.TargetDependents + } + return false +} + +func (x *PreviewRequest) GetPolicyPack() []*PolicyPack { + if x != nil { + return x.PolicyPack + } + return nil +} + +func (x *PreviewRequest) GetRefresh() bool { + if x != nil && x.Refresh != nil { + return *x.Refresh + } + return false +} + +type PolicyPack struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` +} + +func (x *PolicyPack) Reset() { + *x = PolicyPack{} + if protoimpl.UnsafeEnabled { + mi := &file_agent_proto_msgTypes[17] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PolicyPack) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PolicyPack) ProtoMessage() {} + +func (x *PolicyPack) ProtoReflect() protoreflect.Message { + mi := &file_agent_proto_msgTypes[17] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PolicyPack.ProtoReflect.Descriptor instead. +func (*PolicyPack) Descriptor() ([]byte, []int) { + return file_agent_proto_rawDescGZIP(), []int{17} +} + +func (x *PolicyPack) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +type PreviewStream struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Types that are assignable to Response: + // + // *PreviewStream_Event + // *PreviewStream_Result + Response isPreviewStream_Response `protobuf_oneof:"response"` +} + +func (x *PreviewStream) Reset() { + *x = PreviewStream{} + if protoimpl.UnsafeEnabled { + mi := &file_agent_proto_msgTypes[18] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PreviewStream) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PreviewStream) ProtoMessage() {} + +func (x *PreviewStream) ProtoReflect() protoreflect.Message { + mi := &file_agent_proto_msgTypes[18] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PreviewStream.ProtoReflect.Descriptor instead. +func (*PreviewStream) Descriptor() ([]byte, []int) { + return file_agent_proto_rawDescGZIP(), []int{18} +} + +func (m *PreviewStream) GetResponse() isPreviewStream_Response { + if m != nil { + return m.Response + } + return nil +} + +func (x *PreviewStream) GetEvent() *structpb.Struct { + if x, ok := x.GetResponse().(*PreviewStream_Event); ok { + return x.Event + } + return nil +} + +func (x *PreviewStream) GetResult() *PreviewResult { + if x, ok := x.GetResponse().(*PreviewStream_Result); ok { + return x.Result + } + return nil +} + +type isPreviewStream_Response interface { + isPreviewStream_Response() +} + +type PreviewStream_Event struct { + // describes a Pulumi engine event, such as a change to a resource or + // diagnostic message. + Event *structpb.Struct `protobuf:"bytes,1,opt,name=event,proto3,oneof"` +} + +type PreviewStream_Result struct { + Result *PreviewResult `protobuf:"bytes,2,opt,name=result,proto3,oneof"` +} + +func (*PreviewStream_Event) isPreviewStream_Response() {} + +func (*PreviewStream_Result) isPreviewStream_Response() {} + +type PreviewResult struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Stdout string `protobuf:"bytes,1,opt,name=stdout,proto3" json:"stdout,omitempty"` + Stderr string `protobuf:"bytes,2,opt,name=stderr,proto3" json:"stderr,omitempty"` + Summary *UpdateSummary `protobuf:"bytes,3,opt,name=summary,proto3" json:"summary,omitempty"` + Permalink *string `protobuf:"bytes,4,opt,name=permalink,proto3,oneof" json:"permalink,omitempty"` +} + +func (x *PreviewResult) Reset() { + *x = PreviewResult{} + if protoimpl.UnsafeEnabled { + mi := &file_agent_proto_msgTypes[19] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PreviewResult) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PreviewResult) ProtoMessage() {} + +func (x *PreviewResult) ProtoReflect() protoreflect.Message { + mi := &file_agent_proto_msgTypes[19] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PreviewResult.ProtoReflect.Descriptor instead. +func (*PreviewResult) Descriptor() ([]byte, []int) { + return file_agent_proto_rawDescGZIP(), []int{19} +} + +func (x *PreviewResult) GetStdout() string { + if x != nil { + return x.Stdout + } + return "" +} + +func (x *PreviewResult) GetStderr() string { + if x != nil { + return x.Stderr + } + return "" +} + +func (x *PreviewResult) GetSummary() *UpdateSummary { + if x != nil { + return x.Summary + } + return nil +} + +func (x *PreviewResult) GetPermalink() string { + if x != nil && x.Permalink != nil { + return *x.Permalink + } + return "" +} + +type UpRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // parallel is the number of resource operations to run in parallel at once + // (1 for no parallelism). Defaults to unbounded. (default 2147483647) + Parallel *int32 `protobuf:"varint,1,opt,name=parallel,proto3,oneof" json:"parallel,omitempty"` + // message (optional) to associate with the preview operation + Message *string `protobuf:"bytes,2,opt,name=message,proto3,oneof" json:"message,omitempty"` + // Return an error if any changes occur during this update + ExpectNoChanges *bool `protobuf:"varint,3,opt,name=expect_no_changes,json=expectNoChanges,proto3,oneof" json:"expect_no_changes,omitempty"` + // Specify resources to replace + Replace []string `protobuf:"bytes,4,rep,name=replace,proto3" json:"replace,omitempty"` + // Specify an exclusive list of resource URNs to update + Target []string `protobuf:"bytes,5,rep,name=target,proto3" json:"target,omitempty"` + // target_dependents allows updating of dependent targets discovered but not + // specified in the Target list + TargetDependents *bool `protobuf:"varint,6,opt,name=target_dependents,json=targetDependents,proto3,oneof" json:"target_dependents,omitempty"` + // // Use the update plan at the given path. + // optional string plan = 7; + // Run one or more policy packs as part of this update. + PolicyPack []*PolicyPack `protobuf:"bytes,8,rep,name=policy_pack,json=policyPack,proto3" json:"policy_pack,omitempty"` + // refresh will run a refresh before the update. + Refresh *bool `protobuf:"varint,9,opt,name=refresh,proto3,oneof" json:"refresh,omitempty"` + // continue_on_error will continue to perform the update operation despite the + // occurrence of errors. + ContinueOnError *bool `protobuf:"varint,10,opt,name=continue_on_error,json=continueOnError,proto3,oneof" json:"continue_on_error,omitempty"` +} + +func (x *UpRequest) Reset() { + *x = UpRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_agent_proto_msgTypes[20] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpRequest) ProtoMessage() {} + +func (x *UpRequest) ProtoReflect() protoreflect.Message { + mi := &file_agent_proto_msgTypes[20] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpRequest.ProtoReflect.Descriptor instead. +func (*UpRequest) Descriptor() ([]byte, []int) { + return file_agent_proto_rawDescGZIP(), []int{20} +} + +func (x *UpRequest) GetParallel() int32 { + if x != nil && x.Parallel != nil { + return *x.Parallel + } + return 0 +} + +func (x *UpRequest) GetMessage() string { + if x != nil && x.Message != nil { + return *x.Message + } + return "" +} + +func (x *UpRequest) GetExpectNoChanges() bool { + if x != nil && x.ExpectNoChanges != nil { + return *x.ExpectNoChanges + } + return false +} + +func (x *UpRequest) GetReplace() []string { + if x != nil { + return x.Replace + } + return nil +} + +func (x *UpRequest) GetTarget() []string { + if x != nil { + return x.Target + } + return nil +} + +func (x *UpRequest) GetTargetDependents() bool { + if x != nil && x.TargetDependents != nil { + return *x.TargetDependents + } + return false +} + +func (x *UpRequest) GetPolicyPack() []*PolicyPack { + if x != nil { + return x.PolicyPack + } + return nil +} + +func (x *UpRequest) GetRefresh() bool { + if x != nil && x.Refresh != nil { + return *x.Refresh + } + return false +} + +func (x *UpRequest) GetContinueOnError() bool { + if x != nil && x.ContinueOnError != nil { + return *x.ContinueOnError + } + return false +} + +type UpStream struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Types that are assignable to Response: + // + // *UpStream_Event + // *UpStream_Result + Response isUpStream_Response `protobuf_oneof:"response"` +} + +func (x *UpStream) Reset() { + *x = UpStream{} + if protoimpl.UnsafeEnabled { + mi := &file_agent_proto_msgTypes[21] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpStream) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpStream) ProtoMessage() {} + +func (x *UpStream) ProtoReflect() protoreflect.Message { + mi := &file_agent_proto_msgTypes[21] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpStream.ProtoReflect.Descriptor instead. +func (*UpStream) Descriptor() ([]byte, []int) { + return file_agent_proto_rawDescGZIP(), []int{21} +} + +func (m *UpStream) GetResponse() isUpStream_Response { + if m != nil { + return m.Response + } + return nil +} + +func (x *UpStream) GetEvent() *structpb.Struct { + if x, ok := x.GetResponse().(*UpStream_Event); ok { + return x.Event + } + return nil +} + +func (x *UpStream) GetResult() *UpResult { + if x, ok := x.GetResponse().(*UpStream_Result); ok { + return x.Result + } + return nil +} + +type isUpStream_Response interface { + isUpStream_Response() +} + +type UpStream_Event struct { + // describes a Pulumi engine event, such as a change to a resource or + // diagnostic message. + Event *structpb.Struct `protobuf:"bytes,1,opt,name=event,proto3,oneof"` +} + +type UpStream_Result struct { + Result *UpResult `protobuf:"bytes,2,opt,name=result,proto3,oneof"` +} + +func (*UpStream_Event) isUpStream_Response() {} + +func (*UpStream_Result) isUpStream_Response() {} + +type UpResult struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Stdout string `protobuf:"bytes,1,opt,name=stdout,proto3" json:"stdout,omitempty"` + Stderr string `protobuf:"bytes,2,opt,name=stderr,proto3" json:"stderr,omitempty"` + Summary *UpdateSummary `protobuf:"bytes,3,opt,name=summary,proto3" json:"summary,omitempty"` + Permalink *string `protobuf:"bytes,4,opt,name=permalink,proto3,oneof" json:"permalink,omitempty"` +} + +func (x *UpResult) Reset() { + *x = UpResult{} + if protoimpl.UnsafeEnabled { + mi := &file_agent_proto_msgTypes[22] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpResult) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpResult) ProtoMessage() {} + +func (x *UpResult) ProtoReflect() protoreflect.Message { + mi := &file_agent_proto_msgTypes[22] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpResult.ProtoReflect.Descriptor instead. +func (*UpResult) Descriptor() ([]byte, []int) { + return file_agent_proto_rawDescGZIP(), []int{22} +} + +func (x *UpResult) GetStdout() string { + if x != nil { + return x.Stdout + } + return "" +} + +func (x *UpResult) GetStderr() string { + if x != nil { + return x.Stderr + } + return "" +} + +func (x *UpResult) GetSummary() *UpdateSummary { + if x != nil { + return x.Summary + } + return nil +} + +func (x *UpResult) GetPermalink() string { + if x != nil && x.Permalink != nil { + return *x.Permalink + } + return "" +} + +type UpdateSummary struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + StartTime *timestamppb.Timestamp `protobuf:"bytes,1,opt,name=start_time,json=startTime,proto3" json:"start_time,omitempty"` + EndTime *timestamppb.Timestamp `protobuf:"bytes,2,opt,name=end_time,json=endTime,proto3" json:"end_time,omitempty"` + Result string `protobuf:"bytes,3,opt,name=result,proto3" json:"result,omitempty"` + Message string `protobuf:"bytes,4,opt,name=message,proto3" json:"message,omitempty"` +} + +func (x *UpdateSummary) Reset() { + *x = UpdateSummary{} + if protoimpl.UnsafeEnabled { + mi := &file_agent_proto_msgTypes[23] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpdateSummary) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateSummary) ProtoMessage() {} + +func (x *UpdateSummary) ProtoReflect() protoreflect.Message { + mi := &file_agent_proto_msgTypes[23] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateSummary.ProtoReflect.Descriptor instead. +func (*UpdateSummary) Descriptor() ([]byte, []int) { + return file_agent_proto_rawDescGZIP(), []int{23} +} + +func (x *UpdateSummary) GetStartTime() *timestamppb.Timestamp { + if x != nil { + return x.StartTime + } + return nil +} + +func (x *UpdateSummary) GetEndTime() *timestamppb.Timestamp { + if x != nil { + return x.EndTime + } + return nil +} + +func (x *UpdateSummary) GetResult() string { + if x != nil { + return x.Result + } + return "" +} + +func (x *UpdateSummary) GetMessage() string { + if x != nil { + return x.Message + } + return "" +} + +type DestroyRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Parallel is the number of resource operations to run in parallel at once + // (1 for no parallelism). Defaults to unbounded. (default 2147483647) + Parallel *int32 `protobuf:"varint,1,opt,name=parallel,proto3,oneof" json:"parallel,omitempty"` + // Message (optional) to associate with the destroy operation + Message *string `protobuf:"bytes,2,opt,name=message,proto3,oneof" json:"message,omitempty"` + // Specify an exclusive list of resource URNs to destroy + Target []string `protobuf:"bytes,3,rep,name=target,proto3" json:"target,omitempty"` + // Allows updating of dependent targets discovered but not specified in the + // Target list + TargetDependents *bool `protobuf:"varint,4,opt,name=target_dependents,json=targetDependents,proto3,oneof" json:"target_dependents,omitempty"` + // Refresh will run a refresh before the destroy. + Refresh *bool `protobuf:"varint,5,opt,name=refresh,proto3,oneof" json:"refresh,omitempty"` + // continue_on_error will continue to perform the update operation despite the + // occurrence of errors. + ContinueOnError *bool `protobuf:"varint,6,opt,name=continue_on_error,json=continueOnError,proto3,oneof" json:"continue_on_error,omitempty"` + // Remove the stack and its configuration after all resources in the stack + // have been deleted. + Remove *bool `protobuf:"varint,7,opt,name=remove,proto3,oneof" json:"remove,omitempty"` +} + +func (x *DestroyRequest) Reset() { + *x = DestroyRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_agent_proto_msgTypes[24] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DestroyRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DestroyRequest) ProtoMessage() {} + +func (x *DestroyRequest) ProtoReflect() protoreflect.Message { + mi := &file_agent_proto_msgTypes[24] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DestroyRequest.ProtoReflect.Descriptor instead. +func (*DestroyRequest) Descriptor() ([]byte, []int) { + return file_agent_proto_rawDescGZIP(), []int{24} +} + +func (x *DestroyRequest) GetParallel() int32 { + if x != nil && x.Parallel != nil { + return *x.Parallel + } + return 0 +} + +func (x *DestroyRequest) GetMessage() string { + if x != nil && x.Message != nil { + return *x.Message + } + return "" +} + +func (x *DestroyRequest) GetTarget() []string { + if x != nil { + return x.Target + } + return nil +} + +func (x *DestroyRequest) GetTargetDependents() bool { + if x != nil && x.TargetDependents != nil { + return *x.TargetDependents + } + return false +} + +func (x *DestroyRequest) GetRefresh() bool { + if x != nil && x.Refresh != nil { + return *x.Refresh + } + return false +} + +func (x *DestroyRequest) GetContinueOnError() bool { + if x != nil && x.ContinueOnError != nil { + return *x.ContinueOnError + } + return false +} + +func (x *DestroyRequest) GetRemove() bool { + if x != nil && x.Remove != nil { + return *x.Remove + } + return false +} + +type DestroyStream struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Types that are assignable to Response: + // + // *DestroyStream_Event + // *DestroyStream_Result + Response isDestroyStream_Response `protobuf_oneof:"response"` +} + +func (x *DestroyStream) Reset() { + *x = DestroyStream{} + if protoimpl.UnsafeEnabled { + mi := &file_agent_proto_msgTypes[25] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DestroyStream) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DestroyStream) ProtoMessage() {} + +func (x *DestroyStream) ProtoReflect() protoreflect.Message { + mi := &file_agent_proto_msgTypes[25] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DestroyStream.ProtoReflect.Descriptor instead. +func (*DestroyStream) Descriptor() ([]byte, []int) { + return file_agent_proto_rawDescGZIP(), []int{25} +} + +func (m *DestroyStream) GetResponse() isDestroyStream_Response { + if m != nil { + return m.Response + } + return nil +} + +func (x *DestroyStream) GetEvent() *structpb.Struct { + if x, ok := x.GetResponse().(*DestroyStream_Event); ok { + return x.Event + } + return nil +} + +func (x *DestroyStream) GetResult() *DestroyResult { + if x, ok := x.GetResponse().(*DestroyStream_Result); ok { + return x.Result + } + return nil +} + +type isDestroyStream_Response interface { + isDestroyStream_Response() +} + +type DestroyStream_Event struct { + // describes a Pulumi engine event, such as a change to a resource or + // diagnostic message. + Event *structpb.Struct `protobuf:"bytes,1,opt,name=event,proto3,oneof"` +} + +type DestroyStream_Result struct { + Result *DestroyResult `protobuf:"bytes,2,opt,name=result,proto3,oneof"` +} + +func (*DestroyStream_Event) isDestroyStream_Response() {} + +func (*DestroyStream_Result) isDestroyStream_Response() {} + +type DestroyResult struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Stdout string `protobuf:"bytes,1,opt,name=stdout,proto3" json:"stdout,omitempty"` + Stderr string `protobuf:"bytes,2,opt,name=stderr,proto3" json:"stderr,omitempty"` + Summary *UpdateSummary `protobuf:"bytes,3,opt,name=summary,proto3" json:"summary,omitempty"` + Permalink *string `protobuf:"bytes,4,opt,name=permalink,proto3,oneof" json:"permalink,omitempty"` +} + +func (x *DestroyResult) Reset() { + *x = DestroyResult{} + if protoimpl.UnsafeEnabled { + mi := &file_agent_proto_msgTypes[26] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DestroyResult) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DestroyResult) ProtoMessage() {} + +func (x *DestroyResult) ProtoReflect() protoreflect.Message { + mi := &file_agent_proto_msgTypes[26] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DestroyResult.ProtoReflect.Descriptor instead. +func (*DestroyResult) Descriptor() ([]byte, []int) { + return file_agent_proto_rawDescGZIP(), []int{26} +} + +func (x *DestroyResult) GetStdout() string { + if x != nil { + return x.Stdout + } + return "" +} + +func (x *DestroyResult) GetStderr() string { + if x != nil { + return x.Stderr + } + return "" +} + +func (x *DestroyResult) GetSummary() *UpdateSummary { + if x != nil { + return x.Summary + } + return nil +} + +func (x *DestroyResult) GetPermalink() string { + if x != nil && x.Permalink != nil { + return *x.Permalink + } + return "" +} + +var File_agent_proto protoreflect.FileDescriptor + +var file_agent_proto_rawDesc = []byte{ + 0x0a, 0x0b, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x05, 0x61, + 0x67, 0x65, 0x6e, 0x74, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x22, 0x0f, 0x0a, 0x0d, 0x57, 0x68, 0x6f, 0x41, 0x6d, 0x49, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x22, 0x5a, 0x0a, 0x0c, 0x57, 0x68, 0x6f, 0x41, 0x6d, 0x49, 0x52, 0x65, + 0x73, 0x75, 0x6c, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x12, 0x24, 0x0a, 0x0d, 0x6f, 0x72, 0x67, 0x61, + 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, + 0x0d, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x10, + 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, + 0x22, 0xa0, 0x01, 0x0a, 0x12, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x53, 0x74, 0x61, 0x63, 0x6b, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x63, 0x6b, + 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x74, 0x61, + 0x63, 0x6b, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1b, 0x0a, 0x06, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, 0x06, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x88, 0x01, 0x01, 0x12, 0x2e, 0x0a, 0x10, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x5f, 0x70, + 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x48, 0x01, 0x52, + 0x0f, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, + 0x88, 0x01, 0x01, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x42, 0x13, + 0x0a, 0x11, 0x5f, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x5f, 0x70, 0x72, 0x6f, 0x76, 0x69, + 0x64, 0x65, 0x72, 0x22, 0x42, 0x0a, 0x11, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x53, 0x74, 0x61, + 0x63, 0x6b, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x2d, 0x0a, 0x07, 0x73, 0x75, 0x6d, 0x6d, + 0x61, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x61, 0x67, 0x65, 0x6e, + 0x74, 0x2e, 0x53, 0x74, 0x61, 0x63, 0x6b, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x07, + 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x22, 0x0d, 0x0a, 0x0b, 0x49, 0x6e, 0x66, 0x6f, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x3b, 0x0a, 0x0a, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, + 0x73, 0x75, 0x6c, 0x74, 0x12, 0x2d, 0x0a, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x53, 0x74, + 0x61, 0x63, 0x6b, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x07, 0x73, 0x75, 0x6d, 0x6d, + 0x61, 0x72, 0x79, 0x22, 0xeb, 0x01, 0x0a, 0x0c, 0x53, 0x74, 0x61, 0x63, 0x6b, 0x53, 0x75, 0x6d, + 0x6d, 0x61, 0x72, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x3b, 0x0a, 0x0b, 0x6c, 0x61, 0x73, 0x74, + 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, + 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0a, 0x6c, 0x61, 0x73, 0x74, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x2c, 0x0a, 0x12, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, + 0x69, 0x6e, 0x5f, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x10, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x50, 0x72, 0x6f, 0x67, 0x72, + 0x65, 0x73, 0x73, 0x12, 0x2a, 0x0a, 0x0e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, + 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x48, 0x00, 0x52, 0x0d, 0x72, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x88, 0x01, 0x01, 0x12, + 0x15, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x48, 0x01, 0x52, 0x03, + 0x75, 0x72, 0x6c, 0x88, 0x01, 0x01, 0x42, 0x11, 0x0a, 0x0f, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x42, 0x06, 0x0a, 0x04, 0x5f, 0x75, 0x72, + 0x6c, 0x22, 0xc6, 0x01, 0x0a, 0x13, 0x53, 0x65, 0x74, 0x41, 0x6c, 0x6c, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x17, 0x0a, 0x04, 0x70, 0x61, 0x74, + 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x88, + 0x01, 0x01, 0x12, 0x3e, 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x02, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x53, 0x65, 0x74, 0x41, 0x6c, + 0x6c, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x43, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x63, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x1a, 0x4d, 0x0a, 0x0b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x45, 0x6e, 0x74, 0x72, + 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, + 0x6b, 0x65, 0x79, 0x12, 0x28, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, + 0x01, 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x22, 0xa3, 0x01, 0x0a, 0x0b, 0x43, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x2e, 0x0a, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x56, 0x61, 0x6c, 0x75, + 0x65, 0x48, 0x00, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x37, 0x0a, 0x0a, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x5f, 0x66, 0x72, 0x6f, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, + 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x56, 0x61, 0x6c, + 0x75, 0x65, 0x46, 0x72, 0x6f, 0x6d, 0x48, 0x00, 0x52, 0x09, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x46, + 0x72, 0x6f, 0x6d, 0x12, 0x1b, 0x0a, 0x06, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x08, 0x48, 0x01, 0x52, 0x06, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x88, 0x01, 0x01, + 0x42, 0x03, 0x0a, 0x01, 0x76, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, + 0x22, 0x40, 0x0a, 0x0f, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x46, + 0x72, 0x6f, 0x6d, 0x12, 0x12, 0x0a, 0x03, 0x65, 0x6e, 0x76, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x48, 0x00, 0x52, 0x03, 0x65, 0x6e, 0x76, 0x12, 0x14, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x42, 0x03, 0x0a, + 0x01, 0x66, 0x22, 0x14, 0x0a, 0x12, 0x53, 0x65, 0x74, 0x41, 0x6c, 0x6c, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x10, 0x0a, 0x0e, 0x49, 0x6e, 0x73, 0x74, + 0x61, 0x6c, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x0f, 0x0a, 0x0d, 0x49, 0x6e, + 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0xc8, 0x01, 0x0a, 0x0e, + 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, + 0x0a, 0x08, 0x70, 0x61, 0x72, 0x61, 0x6c, 0x6c, 0x65, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, + 0x48, 0x00, 0x52, 0x08, 0x70, 0x61, 0x72, 0x61, 0x6c, 0x6c, 0x65, 0x6c, 0x88, 0x01, 0x01, 0x12, + 0x1d, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x48, 0x01, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x88, 0x01, 0x01, 0x12, 0x2f, + 0x0a, 0x11, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, 0x5f, 0x6e, 0x6f, 0x5f, 0x63, 0x68, 0x61, 0x6e, + 0x67, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x48, 0x02, 0x52, 0x0f, 0x65, 0x78, 0x70, + 0x65, 0x63, 0x74, 0x4e, 0x6f, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x88, 0x01, 0x01, 0x12, + 0x16, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, + 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x70, 0x61, 0x72, 0x61, + 0x6c, 0x6c, 0x65, 0x6c, 0x42, 0x0a, 0x0a, 0x08, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x42, 0x14, 0x0a, 0x12, 0x5f, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, 0x5f, 0x6e, 0x6f, 0x5f, 0x63, + 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x22, 0x7c, 0x0a, 0x0d, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, + 0x68, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x2f, 0x0a, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x48, + 0x00, 0x52, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x2e, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, + 0x6c, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, + 0x2e, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x48, 0x00, + 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x42, 0x0a, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xa0, 0x01, 0x0a, 0x0d, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, + 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x64, 0x6f, 0x75, 0x74, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x64, 0x6f, 0x75, 0x74, 0x12, 0x16, + 0x0a, 0x06, 0x73, 0x74, 0x64, 0x65, 0x72, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, + 0x73, 0x74, 0x64, 0x65, 0x72, 0x72, 0x12, 0x2e, 0x0a, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, + 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, + 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x07, 0x73, + 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x21, 0x0a, 0x09, 0x70, 0x65, 0x72, 0x6d, 0x61, 0x6c, + 0x69, 0x6e, 0x6b, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x09, 0x70, 0x65, 0x72, + 0x6d, 0x61, 0x6c, 0x69, 0x6e, 0x6b, 0x88, 0x01, 0x01, 0x42, 0x0c, 0x0a, 0x0a, 0x5f, 0x70, 0x65, + 0x72, 0x6d, 0x61, 0x6c, 0x69, 0x6e, 0x6b, 0x22, 0x89, 0x03, 0x0a, 0x0e, 0x50, 0x72, 0x65, 0x76, + 0x69, 0x65, 0x77, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x08, 0x70, 0x61, + 0x72, 0x61, 0x6c, 0x6c, 0x65, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x48, 0x00, 0x52, 0x08, + 0x70, 0x61, 0x72, 0x61, 0x6c, 0x6c, 0x65, 0x6c, 0x88, 0x01, 0x01, 0x12, 0x1d, 0x0a, 0x07, 0x6d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x01, 0x52, 0x07, + 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x88, 0x01, 0x01, 0x12, 0x2f, 0x0a, 0x11, 0x65, 0x78, + 0x70, 0x65, 0x63, 0x74, 0x5f, 0x6e, 0x6f, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x08, 0x48, 0x02, 0x52, 0x0f, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, 0x4e, + 0x6f, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x88, 0x01, 0x01, 0x12, 0x18, 0x0a, 0x07, 0x72, + 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x72, 0x65, + 0x70, 0x6c, 0x61, 0x63, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, + 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x30, 0x0a, + 0x11, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x64, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x65, 0x6e, + 0x74, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x48, 0x03, 0x52, 0x10, 0x74, 0x61, 0x72, 0x67, + 0x65, 0x74, 0x44, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x65, 0x6e, 0x74, 0x73, 0x88, 0x01, 0x01, 0x12, + 0x32, 0x0a, 0x0b, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, 0x70, 0x61, 0x63, 0x6b, 0x18, 0x07, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x50, 0x6f, 0x6c, + 0x69, 0x63, 0x79, 0x50, 0x61, 0x63, 0x6b, 0x52, 0x0a, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x50, + 0x61, 0x63, 0x6b, 0x12, 0x1d, 0x0a, 0x07, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x18, 0x08, + 0x20, 0x01, 0x28, 0x08, 0x48, 0x04, 0x52, 0x07, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x88, + 0x01, 0x01, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6c, 0x6c, 0x65, 0x6c, 0x42, + 0x0a, 0x0a, 0x08, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x42, 0x14, 0x0a, 0x12, 0x5f, + 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, 0x5f, 0x6e, 0x6f, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, + 0x73, 0x42, 0x14, 0x0a, 0x12, 0x5f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x64, 0x65, 0x70, + 0x65, 0x6e, 0x64, 0x65, 0x6e, 0x74, 0x73, 0x42, 0x0a, 0x0a, 0x08, 0x5f, 0x72, 0x65, 0x66, 0x72, + 0x65, 0x73, 0x68, 0x22, 0x20, 0x0a, 0x0a, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x50, 0x61, 0x63, + 0x6b, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x7c, 0x0a, 0x0d, 0x50, 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, + 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x2f, 0x0a, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x48, 0x00, + 0x52, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x2e, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, + 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, + 0x50, 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x48, 0x00, 0x52, + 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x42, 0x0a, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0xa0, 0x01, 0x0a, 0x0d, 0x50, 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0x52, + 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x64, 0x6f, 0x75, 0x74, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x64, 0x6f, 0x75, 0x74, 0x12, 0x16, 0x0a, + 0x06, 0x73, 0x74, 0x64, 0x65, 0x72, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, + 0x74, 0x64, 0x65, 0x72, 0x72, 0x12, 0x2e, 0x0a, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x07, 0x73, 0x75, + 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x21, 0x0a, 0x09, 0x70, 0x65, 0x72, 0x6d, 0x61, 0x6c, 0x69, + 0x6e, 0x6b, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x09, 0x70, 0x65, 0x72, 0x6d, + 0x61, 0x6c, 0x69, 0x6e, 0x6b, 0x88, 0x01, 0x01, 0x42, 0x0c, 0x0a, 0x0a, 0x5f, 0x70, 0x65, 0x72, + 0x6d, 0x61, 0x6c, 0x69, 0x6e, 0x6b, 0x22, 0xcb, 0x03, 0x0a, 0x09, 0x55, 0x70, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x08, 0x70, 0x61, 0x72, 0x61, 0x6c, 0x6c, 0x65, 0x6c, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x48, 0x00, 0x52, 0x08, 0x70, 0x61, 0x72, 0x61, 0x6c, 0x6c, + 0x65, 0x6c, 0x88, 0x01, 0x01, 0x12, 0x1d, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x01, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x88, 0x01, 0x01, 0x12, 0x2f, 0x0a, 0x11, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, 0x5f, 0x6e, + 0x6f, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x48, + 0x02, 0x52, 0x0f, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, 0x4e, 0x6f, 0x43, 0x68, 0x61, 0x6e, 0x67, + 0x65, 0x73, 0x88, 0x01, 0x01, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, + 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x12, + 0x16, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, + 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x30, 0x0a, 0x11, 0x74, 0x61, 0x72, 0x67, 0x65, + 0x74, 0x5f, 0x64, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x08, 0x48, 0x03, 0x52, 0x10, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x44, 0x65, 0x70, 0x65, + 0x6e, 0x64, 0x65, 0x6e, 0x74, 0x73, 0x88, 0x01, 0x01, 0x12, 0x32, 0x0a, 0x0b, 0x70, 0x6f, 0x6c, + 0x69, 0x63, 0x79, 0x5f, 0x70, 0x61, 0x63, 0x6b, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, + 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x50, 0x61, 0x63, + 0x6b, 0x52, 0x0a, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x50, 0x61, 0x63, 0x6b, 0x12, 0x1d, 0x0a, + 0x07, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x18, 0x09, 0x20, 0x01, 0x28, 0x08, 0x48, 0x04, + 0x52, 0x07, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x88, 0x01, 0x01, 0x12, 0x2f, 0x0a, 0x11, + 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x65, 0x5f, 0x6f, 0x6e, 0x5f, 0x65, 0x72, 0x72, 0x6f, + 0x72, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x48, 0x05, 0x52, 0x0f, 0x63, 0x6f, 0x6e, 0x74, 0x69, + 0x6e, 0x75, 0x65, 0x4f, 0x6e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x88, 0x01, 0x01, 0x42, 0x0b, 0x0a, + 0x09, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6c, 0x6c, 0x65, 0x6c, 0x42, 0x0a, 0x0a, 0x08, 0x5f, 0x6d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x42, 0x14, 0x0a, 0x12, 0x5f, 0x65, 0x78, 0x70, 0x65, 0x63, + 0x74, 0x5f, 0x6e, 0x6f, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x42, 0x14, 0x0a, 0x12, + 0x5f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x64, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x65, 0x6e, + 0x74, 0x73, 0x42, 0x0a, 0x0a, 0x08, 0x5f, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x42, 0x14, + 0x0a, 0x12, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x65, 0x5f, 0x6f, 0x6e, 0x5f, 0x65, + 0x72, 0x72, 0x6f, 0x72, 0x22, 0x72, 0x0a, 0x08, 0x55, 0x70, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, + 0x12, 0x2f, 0x0a, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x48, 0x00, 0x52, 0x05, 0x65, 0x76, 0x65, 0x6e, + 0x74, 0x12, 0x29, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x0f, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x55, 0x70, 0x52, 0x65, 0x73, 0x75, + 0x6c, 0x74, 0x48, 0x00, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x42, 0x0a, 0x0a, 0x08, + 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x9b, 0x01, 0x0a, 0x08, 0x55, 0x70, 0x52, + 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x64, 0x6f, 0x75, 0x74, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x64, 0x6f, 0x75, 0x74, 0x12, 0x16, 0x0a, + 0x06, 0x73, 0x74, 0x64, 0x65, 0x72, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, + 0x74, 0x64, 0x65, 0x72, 0x72, 0x12, 0x2e, 0x0a, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x07, 0x73, 0x75, + 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x21, 0x0a, 0x09, 0x70, 0x65, 0x72, 0x6d, 0x61, 0x6c, 0x69, + 0x6e, 0x6b, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x09, 0x70, 0x65, 0x72, 0x6d, + 0x61, 0x6c, 0x69, 0x6e, 0x6b, 0x88, 0x01, 0x01, 0x42, 0x0c, 0x0a, 0x0a, 0x5f, 0x70, 0x65, 0x72, + 0x6d, 0x61, 0x6c, 0x69, 0x6e, 0x6b, 0x22, 0xb3, 0x01, 0x0a, 0x0d, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x39, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x72, + 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, + 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x54, + 0x69, 0x6d, 0x65, 0x12, 0x35, 0x0a, 0x08, 0x65, 0x6e, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, + 0x70, 0x52, 0x07, 0x65, 0x6e, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, + 0x73, 0x75, 0x6c, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, + 0x6c, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0xe3, 0x02, 0x0a, + 0x0e, 0x44, 0x65, 0x73, 0x74, 0x72, 0x6f, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x1f, 0x0a, 0x08, 0x70, 0x61, 0x72, 0x61, 0x6c, 0x6c, 0x65, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x05, 0x48, 0x00, 0x52, 0x08, 0x70, 0x61, 0x72, 0x61, 0x6c, 0x6c, 0x65, 0x6c, 0x88, 0x01, 0x01, + 0x12, 0x1d, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x48, 0x01, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x88, 0x01, 0x01, 0x12, + 0x16, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, + 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x30, 0x0a, 0x11, 0x74, 0x61, 0x72, 0x67, 0x65, + 0x74, 0x5f, 0x64, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x08, 0x48, 0x02, 0x52, 0x10, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x44, 0x65, 0x70, 0x65, + 0x6e, 0x64, 0x65, 0x6e, 0x74, 0x73, 0x88, 0x01, 0x01, 0x12, 0x1d, 0x0a, 0x07, 0x72, 0x65, 0x66, + 0x72, 0x65, 0x73, 0x68, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x48, 0x03, 0x52, 0x07, 0x72, 0x65, + 0x66, 0x72, 0x65, 0x73, 0x68, 0x88, 0x01, 0x01, 0x12, 0x2f, 0x0a, 0x11, 0x63, 0x6f, 0x6e, 0x74, + 0x69, 0x6e, 0x75, 0x65, 0x5f, 0x6f, 0x6e, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x08, 0x48, 0x04, 0x52, 0x0f, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x65, 0x4f, + 0x6e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x88, 0x01, 0x01, 0x12, 0x1b, 0x0a, 0x06, 0x72, 0x65, 0x6d, + 0x6f, 0x76, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x48, 0x05, 0x52, 0x06, 0x72, 0x65, 0x6d, + 0x6f, 0x76, 0x65, 0x88, 0x01, 0x01, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6c, + 0x6c, 0x65, 0x6c, 0x42, 0x0a, 0x0a, 0x08, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x42, + 0x14, 0x0a, 0x12, 0x5f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x64, 0x65, 0x70, 0x65, 0x6e, + 0x64, 0x65, 0x6e, 0x74, 0x73, 0x42, 0x0a, 0x0a, 0x08, 0x5f, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, + 0x68, 0x42, 0x14, 0x0a, 0x12, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x65, 0x5f, 0x6f, + 0x6e, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x72, 0x65, 0x6d, 0x6f, + 0x76, 0x65, 0x22, 0x7c, 0x0a, 0x0d, 0x44, 0x65, 0x73, 0x74, 0x72, 0x6f, 0x79, 0x53, 0x74, 0x72, + 0x65, 0x61, 0x6d, 0x12, 0x2f, 0x0a, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x48, 0x00, 0x52, 0x05, 0x65, + 0x76, 0x65, 0x6e, 0x74, 0x12, 0x2e, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x44, 0x65, 0x73, + 0x74, 0x72, 0x6f, 0x79, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x48, 0x00, 0x52, 0x06, 0x72, 0x65, + 0x73, 0x75, 0x6c, 0x74, 0x42, 0x0a, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0xa0, 0x01, 0x0a, 0x0d, 0x44, 0x65, 0x73, 0x74, 0x72, 0x6f, 0x79, 0x52, 0x65, 0x73, 0x75, + 0x6c, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x64, 0x6f, 0x75, 0x74, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x64, 0x6f, 0x75, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, + 0x64, 0x65, 0x72, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x64, 0x65, + 0x72, 0x72, 0x12, 0x2e, 0x0a, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x55, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, + 0x72, 0x79, 0x12, 0x21, 0x0a, 0x09, 0x70, 0x65, 0x72, 0x6d, 0x61, 0x6c, 0x69, 0x6e, 0x6b, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x09, 0x70, 0x65, 0x72, 0x6d, 0x61, 0x6c, 0x69, + 0x6e, 0x6b, 0x88, 0x01, 0x01, 0x42, 0x0c, 0x0a, 0x0a, 0x5f, 0x70, 0x65, 0x72, 0x6d, 0x61, 0x6c, + 0x69, 0x6e, 0x6b, 0x32, 0xa5, 0x04, 0x0a, 0x11, 0x41, 0x75, 0x74, 0x6f, 0x6d, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x35, 0x0a, 0x06, 0x57, 0x68, 0x6f, + 0x41, 0x6d, 0x49, 0x12, 0x14, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x57, 0x68, 0x6f, 0x41, + 0x6d, 0x49, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x61, 0x67, 0x65, 0x6e, + 0x74, 0x2e, 0x57, 0x68, 0x6f, 0x41, 0x6d, 0x49, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x00, + 0x12, 0x44, 0x0a, 0x0b, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x53, 0x74, 0x61, 0x63, 0x6b, 0x12, + 0x19, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x53, 0x74, + 0x61, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x61, 0x67, 0x65, + 0x6e, 0x74, 0x2e, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x53, 0x74, 0x61, 0x63, 0x6b, 0x52, 0x65, + 0x73, 0x75, 0x6c, 0x74, 0x22, 0x00, 0x12, 0x2f, 0x0a, 0x04, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x12, + 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x11, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x49, 0x6e, 0x66, 0x6f, 0x52, + 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x00, 0x12, 0x47, 0x0a, 0x0c, 0x53, 0x65, 0x74, 0x41, 0x6c, + 0x6c, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x1a, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, + 0x53, 0x65, 0x74, 0x41, 0x6c, 0x6c, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x53, 0x65, 0x74, 0x41, + 0x6c, 0x6c, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x00, + 0x12, 0x38, 0x0a, 0x07, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x12, 0x15, 0x2e, 0x61, 0x67, + 0x65, 0x6e, 0x74, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, + 0x6c, 0x6c, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x00, 0x12, 0x3a, 0x0a, 0x07, 0x50, 0x72, + 0x65, 0x76, 0x69, 0x65, 0x77, 0x12, 0x15, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x50, 0x72, + 0x65, 0x76, 0x69, 0x65, 0x77, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x61, + 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x50, 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0x53, 0x74, 0x72, 0x65, + 0x61, 0x6d, 0x22, 0x00, 0x30, 0x01, 0x12, 0x3a, 0x0a, 0x07, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, + 0x68, 0x12, 0x15, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, + 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, + 0x2e, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x22, 0x00, + 0x30, 0x01, 0x12, 0x2b, 0x0a, 0x02, 0x55, 0x70, 0x12, 0x10, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, + 0x2e, 0x55, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0f, 0x2e, 0x61, 0x67, 0x65, + 0x6e, 0x74, 0x2e, 0x55, 0x70, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x22, 0x00, 0x30, 0x01, 0x12, + 0x3a, 0x0a, 0x07, 0x44, 0x65, 0x73, 0x74, 0x72, 0x6f, 0x79, 0x12, 0x15, 0x2e, 0x61, 0x67, 0x65, + 0x6e, 0x74, 0x2e, 0x44, 0x65, 0x73, 0x74, 0x72, 0x6f, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x14, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x44, 0x65, 0x73, 0x74, 0x72, 0x6f, + 0x79, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x22, 0x00, 0x30, 0x01, 0x42, 0x3e, 0x5a, 0x3c, 0x67, + 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x75, 0x6c, 0x75, 0x6d, 0x69, + 0x2f, 0x70, 0x75, 0x6c, 0x75, 0x6d, 0x69, 0x2d, 0x6b, 0x75, 0x62, 0x65, 0x72, 0x6e, 0x65, 0x74, + 0x65, 0x73, 0x2d, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x2f, 0x61, 0x67, 0x65, 0x6e, + 0x74, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x33, +} + +var ( + file_agent_proto_rawDescOnce sync.Once + file_agent_proto_rawDescData = file_agent_proto_rawDesc +) + +func file_agent_proto_rawDescGZIP() []byte { + file_agent_proto_rawDescOnce.Do(func() { + file_agent_proto_rawDescData = protoimpl.X.CompressGZIP(file_agent_proto_rawDescData) + }) + return file_agent_proto_rawDescData +} + +var file_agent_proto_msgTypes = make([]protoimpl.MessageInfo, 28) +var file_agent_proto_goTypes = []any{ + (*WhoAmIRequest)(nil), // 0: agent.WhoAmIRequest + (*WhoAmIResult)(nil), // 1: agent.WhoAmIResult + (*SelectStackRequest)(nil), // 2: agent.SelectStackRequest + (*SelectStackResult)(nil), // 3: agent.SelectStackResult + (*InfoRequest)(nil), // 4: agent.InfoRequest + (*InfoResult)(nil), // 5: agent.InfoResult + (*StackSummary)(nil), // 6: agent.StackSummary + (*SetAllConfigRequest)(nil), // 7: agent.SetAllConfigRequest + (*ConfigValue)(nil), // 8: agent.ConfigValue + (*ConfigValueFrom)(nil), // 9: agent.ConfigValueFrom + (*SetAllConfigResult)(nil), // 10: agent.SetAllConfigResult + (*InstallRequest)(nil), // 11: agent.InstallRequest + (*InstallResult)(nil), // 12: agent.InstallResult + (*RefreshRequest)(nil), // 13: agent.RefreshRequest + (*RefreshStream)(nil), // 14: agent.RefreshStream + (*RefreshResult)(nil), // 15: agent.RefreshResult + (*PreviewRequest)(nil), // 16: agent.PreviewRequest + (*PolicyPack)(nil), // 17: agent.PolicyPack + (*PreviewStream)(nil), // 18: agent.PreviewStream + (*PreviewResult)(nil), // 19: agent.PreviewResult + (*UpRequest)(nil), // 20: agent.UpRequest + (*UpStream)(nil), // 21: agent.UpStream + (*UpResult)(nil), // 22: agent.UpResult + (*UpdateSummary)(nil), // 23: agent.UpdateSummary + (*DestroyRequest)(nil), // 24: agent.DestroyRequest + (*DestroyStream)(nil), // 25: agent.DestroyStream + (*DestroyResult)(nil), // 26: agent.DestroyResult + nil, // 27: agent.SetAllConfigRequest.ConfigEntry + (*timestamppb.Timestamp)(nil), // 28: google.protobuf.Timestamp + (*structpb.Value)(nil), // 29: google.protobuf.Value + (*structpb.Struct)(nil), // 30: google.protobuf.Struct +} +var file_agent_proto_depIdxs = []int32{ + 6, // 0: agent.SelectStackResult.summary:type_name -> agent.StackSummary + 6, // 1: agent.InfoResult.summary:type_name -> agent.StackSummary + 28, // 2: agent.StackSummary.last_update:type_name -> google.protobuf.Timestamp + 27, // 3: agent.SetAllConfigRequest.config:type_name -> agent.SetAllConfigRequest.ConfigEntry + 29, // 4: agent.ConfigValue.value:type_name -> google.protobuf.Value + 9, // 5: agent.ConfigValue.value_from:type_name -> agent.ConfigValueFrom + 30, // 6: agent.RefreshStream.event:type_name -> google.protobuf.Struct + 15, // 7: agent.RefreshStream.result:type_name -> agent.RefreshResult + 23, // 8: agent.RefreshResult.summary:type_name -> agent.UpdateSummary + 17, // 9: agent.PreviewRequest.policy_pack:type_name -> agent.PolicyPack + 30, // 10: agent.PreviewStream.event:type_name -> google.protobuf.Struct + 19, // 11: agent.PreviewStream.result:type_name -> agent.PreviewResult + 23, // 12: agent.PreviewResult.summary:type_name -> agent.UpdateSummary + 17, // 13: agent.UpRequest.policy_pack:type_name -> agent.PolicyPack + 30, // 14: agent.UpStream.event:type_name -> google.protobuf.Struct + 22, // 15: agent.UpStream.result:type_name -> agent.UpResult + 23, // 16: agent.UpResult.summary:type_name -> agent.UpdateSummary + 28, // 17: agent.UpdateSummary.start_time:type_name -> google.protobuf.Timestamp + 28, // 18: agent.UpdateSummary.end_time:type_name -> google.protobuf.Timestamp + 30, // 19: agent.DestroyStream.event:type_name -> google.protobuf.Struct + 26, // 20: agent.DestroyStream.result:type_name -> agent.DestroyResult + 23, // 21: agent.DestroyResult.summary:type_name -> agent.UpdateSummary + 8, // 22: agent.SetAllConfigRequest.ConfigEntry.value:type_name -> agent.ConfigValue + 0, // 23: agent.AutomationService.WhoAmI:input_type -> agent.WhoAmIRequest + 2, // 24: agent.AutomationService.SelectStack:input_type -> agent.SelectStackRequest + 4, // 25: agent.AutomationService.Info:input_type -> agent.InfoRequest + 7, // 26: agent.AutomationService.SetAllConfig:input_type -> agent.SetAllConfigRequest + 11, // 27: agent.AutomationService.Install:input_type -> agent.InstallRequest + 16, // 28: agent.AutomationService.Preview:input_type -> agent.PreviewRequest + 13, // 29: agent.AutomationService.Refresh:input_type -> agent.RefreshRequest + 20, // 30: agent.AutomationService.Up:input_type -> agent.UpRequest + 24, // 31: agent.AutomationService.Destroy:input_type -> agent.DestroyRequest + 1, // 32: agent.AutomationService.WhoAmI:output_type -> agent.WhoAmIResult + 3, // 33: agent.AutomationService.SelectStack:output_type -> agent.SelectStackResult + 5, // 34: agent.AutomationService.Info:output_type -> agent.InfoResult + 10, // 35: agent.AutomationService.SetAllConfig:output_type -> agent.SetAllConfigResult + 12, // 36: agent.AutomationService.Install:output_type -> agent.InstallResult + 18, // 37: agent.AutomationService.Preview:output_type -> agent.PreviewStream + 14, // 38: agent.AutomationService.Refresh:output_type -> agent.RefreshStream + 21, // 39: agent.AutomationService.Up:output_type -> agent.UpStream + 25, // 40: agent.AutomationService.Destroy:output_type -> agent.DestroyStream + 32, // [32:41] is the sub-list for method output_type + 23, // [23:32] is the sub-list for method input_type + 23, // [23:23] is the sub-list for extension type_name + 23, // [23:23] is the sub-list for extension extendee + 0, // [0:23] is the sub-list for field type_name +} + +func init() { file_agent_proto_init() } +func file_agent_proto_init() { + if File_agent_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_agent_proto_msgTypes[0].Exporter = func(v any, i int) any { + switch v := v.(*WhoAmIRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_agent_proto_msgTypes[1].Exporter = func(v any, i int) any { + switch v := v.(*WhoAmIResult); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_agent_proto_msgTypes[2].Exporter = func(v any, i int) any { + switch v := v.(*SelectStackRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_agent_proto_msgTypes[3].Exporter = func(v any, i int) any { + switch v := v.(*SelectStackResult); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_agent_proto_msgTypes[4].Exporter = func(v any, i int) any { + switch v := v.(*InfoRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_agent_proto_msgTypes[5].Exporter = func(v any, i int) any { + switch v := v.(*InfoResult); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_agent_proto_msgTypes[6].Exporter = func(v any, i int) any { + switch v := v.(*StackSummary); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_agent_proto_msgTypes[7].Exporter = func(v any, i int) any { + switch v := v.(*SetAllConfigRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_agent_proto_msgTypes[8].Exporter = func(v any, i int) any { + switch v := v.(*ConfigValue); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_agent_proto_msgTypes[9].Exporter = func(v any, i int) any { + switch v := v.(*ConfigValueFrom); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_agent_proto_msgTypes[10].Exporter = func(v any, i int) any { + switch v := v.(*SetAllConfigResult); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_agent_proto_msgTypes[11].Exporter = func(v any, i int) any { + switch v := v.(*InstallRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_agent_proto_msgTypes[12].Exporter = func(v any, i int) any { + switch v := v.(*InstallResult); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_agent_proto_msgTypes[13].Exporter = func(v any, i int) any { + switch v := v.(*RefreshRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_agent_proto_msgTypes[14].Exporter = func(v any, i int) any { + switch v := v.(*RefreshStream); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_agent_proto_msgTypes[15].Exporter = func(v any, i int) any { + switch v := v.(*RefreshResult); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_agent_proto_msgTypes[16].Exporter = func(v any, i int) any { + switch v := v.(*PreviewRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_agent_proto_msgTypes[17].Exporter = func(v any, i int) any { + switch v := v.(*PolicyPack); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_agent_proto_msgTypes[18].Exporter = func(v any, i int) any { + switch v := v.(*PreviewStream); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_agent_proto_msgTypes[19].Exporter = func(v any, i int) any { + switch v := v.(*PreviewResult); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_agent_proto_msgTypes[20].Exporter = func(v any, i int) any { + switch v := v.(*UpRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_agent_proto_msgTypes[21].Exporter = func(v any, i int) any { + switch v := v.(*UpStream); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_agent_proto_msgTypes[22].Exporter = func(v any, i int) any { + switch v := v.(*UpResult); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_agent_proto_msgTypes[23].Exporter = func(v any, i int) any { + switch v := v.(*UpdateSummary); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_agent_proto_msgTypes[24].Exporter = func(v any, i int) any { + switch v := v.(*DestroyRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_agent_proto_msgTypes[25].Exporter = func(v any, i int) any { + switch v := v.(*DestroyStream); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_agent_proto_msgTypes[26].Exporter = func(v any, i int) any { + switch v := v.(*DestroyResult); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + file_agent_proto_msgTypes[2].OneofWrappers = []any{} + file_agent_proto_msgTypes[6].OneofWrappers = []any{} + file_agent_proto_msgTypes[7].OneofWrappers = []any{} + file_agent_proto_msgTypes[8].OneofWrappers = []any{ + (*ConfigValue_Value)(nil), + (*ConfigValue_ValueFrom)(nil), + } + file_agent_proto_msgTypes[9].OneofWrappers = []any{ + (*ConfigValueFrom_Env)(nil), + (*ConfigValueFrom_Path)(nil), + } + file_agent_proto_msgTypes[13].OneofWrappers = []any{} + file_agent_proto_msgTypes[14].OneofWrappers = []any{ + (*RefreshStream_Event)(nil), + (*RefreshStream_Result)(nil), + } + file_agent_proto_msgTypes[15].OneofWrappers = []any{} + file_agent_proto_msgTypes[16].OneofWrappers = []any{} + file_agent_proto_msgTypes[18].OneofWrappers = []any{ + (*PreviewStream_Event)(nil), + (*PreviewStream_Result)(nil), + } + file_agent_proto_msgTypes[19].OneofWrappers = []any{} + file_agent_proto_msgTypes[20].OneofWrappers = []any{} + file_agent_proto_msgTypes[21].OneofWrappers = []any{ + (*UpStream_Event)(nil), + (*UpStream_Result)(nil), + } + file_agent_proto_msgTypes[22].OneofWrappers = []any{} + file_agent_proto_msgTypes[24].OneofWrappers = []any{} + file_agent_proto_msgTypes[25].OneofWrappers = []any{ + (*DestroyStream_Event)(nil), + (*DestroyStream_Result)(nil), + } + file_agent_proto_msgTypes[26].OneofWrappers = []any{} + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_agent_proto_rawDesc, + NumEnums: 0, + NumMessages: 28, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_agent_proto_goTypes, + DependencyIndexes: file_agent_proto_depIdxs, + MessageInfos: file_agent_proto_msgTypes, + }.Build() + File_agent_proto = out.File + file_agent_proto_rawDesc = nil + file_agent_proto_goTypes = nil + file_agent_proto_depIdxs = nil +} diff --git a/agent/pkg/proto/agent.proto b/agent/pkg/proto/agent.proto new file mode 100644 index 00000000..aef2ba78 --- /dev/null +++ b/agent/pkg/proto/agent.proto @@ -0,0 +1,272 @@ +syntax = "proto3"; + +import "google/protobuf/struct.proto"; +import "google/protobuf/timestamp.proto"; + +option go_package = "github.com/pulumi/pulumi-kubernetes-operator/agent/pkg/proto"; + +package agent; + +service AutomationService { + + /** + * WhoAmI returns detailed information about the currently logged-in Pulumi + * identity. + */ + rpc WhoAmI(WhoAmIRequest) returns (WhoAmIResult) {} + + /** + * Info returns information about the given stack. + */ + rpc SelectStack(SelectStackRequest) returns (SelectStackResult) {} + + /** + * Info returns information about the given stack. + */ + rpc Info(InfoRequest) returns (InfoResult) {} + + /** + * SetAllConfig sets multiple configuration values for a stack. + */ + rpc SetAllConfig(SetAllConfigRequest) returns (SetAllConfigResult) {} + + /** + * Install installs the Pulumi plugins and dependencies. + */ + rpc Install(InstallRequest) returns (InstallResult) {} + + /** + * Preview performs a dry-run update to a stack, returning the expected + * changes. + */ + rpc Preview(PreviewRequest) returns (stream PreviewStream) {} + + /** + * Refresh updates the resources in a stack to match the current state of the + * cloud provider. + */ + rpc Refresh(RefreshRequest) returns (stream RefreshStream) {} + + /** + * Up creates or updates the resources in a stack, returning the actual + * changes. + */ + rpc Up(UpRequest) returns (stream UpStream) {} + + /** + * Destroy deletes all resources in a stack. + */ + rpc Destroy(DestroyRequest) returns (stream DestroyStream) {} +} + +message WhoAmIRequest {} + +// WhoAmIResult contains detailed information about the currently logged-in +// Pulumi identity. +message WhoAmIResult { + string user = 1; + repeated string organizations = 2; + string url = 3; +} + +message SelectStackRequest { + string stack_name = 1; + optional bool create = 2; + optional string secrets_provider = 3; +} + +message SelectStackResult { StackSummary summary = 1; } + +message InfoRequest {} + +message InfoResult { StackSummary summary = 1; } + +// StackSummary is a description of a stack and its current status. +message StackSummary { + string name = 1; + google.protobuf.Timestamp last_update = 2; + bool update_in_progress = 3; + optional int32 resource_count = 4; + optional string url = 5; +} + +message SetAllConfigRequest { + optional bool path = + 1; // Parse the keys as paths in a map or list rather than raw strings + map config = + 2; // a map of ConfigValue used by Pulumi programs +} + +message ConfigValue { + oneof v { + google.protobuf.Value value = 1; + ConfigValueFrom value_from = 2; + } + optional bool secret = 3; +} + +message ConfigValueFrom { + oneof f { + string env = 1; // the name of an environment variable to read + string path = 2; // the path to a file to read + } +} + +message SetAllConfigResult {} + +message InstallRequest {} + +message InstallResult {} + +message RefreshRequest { + // parallel is the number of resource operations to run in parallel at once + // (1 for no parallelism). Defaults to unbounded. (default 2147483647) + optional int32 parallel = 1; + // message (optional) to associate with the preview operation + optional string message = 2; + // Return an error if any changes occur during this refresh + optional bool expect_no_changes = 3; + // Specify an exclusive list of resource URNs to refresh + repeated string target = 4; +} + +message RefreshStream { + oneof response { + // describes a Pulumi engine event, such as a change to a resource or + // diagnostic message. + google.protobuf.Struct event = 1; + RefreshResult result = 2; + } +} + +message RefreshResult { + string stdout = 1; + string stderr = 2; + UpdateSummary summary = 3; + optional string permalink = 4; +} + +message PreviewRequest { + // Parallel is the number of resource operations to run in parallel at once + // (1 for no parallelism). Defaults to unbounded. (default 2147483647) + optional int32 parallel = 1; + // Message (optional) to associate with the preview operation + optional string message = 2; + // Return an error if any changes occur during this preview + optional bool expect_no_changes = 3; + // Specify resources to replace + repeated string replace = 4; + // Specify an exclusive list of resource URNs to update + repeated string target = 5; + // Allows updating of dependent targets discovered but not specified in the + // Target list + optional bool target_dependents = 6; + // Run one or more policy packs as part of this update + repeated PolicyPack policy_pack = 7; + // Refresh will run a refresh before the preview. + optional bool refresh = 8; +} + +message PolicyPack { string name = 1; } + +message PreviewStream { + oneof response { + // describes a Pulumi engine event, such as a change to a resource or + // diagnostic message. + google.protobuf.Struct event = 1; + PreviewResult result = 2; + } +} + +message PreviewResult { + string stdout = 1; + string stderr = 2; + UpdateSummary summary = 3; + optional string permalink = 4; +} + +message UpRequest { + // parallel is the number of resource operations to run in parallel at once + // (1 for no parallelism). Defaults to unbounded. (default 2147483647) + optional int32 parallel = 1; + // message (optional) to associate with the preview operation + optional string message = 2; + // Return an error if any changes occur during this update + optional bool expect_no_changes = 3; + // Specify resources to replace + repeated string replace = 4; + // Specify an exclusive list of resource URNs to update + repeated string target = 5; + // target_dependents allows updating of dependent targets discovered but not + // specified in the Target list + optional bool target_dependents = 6; + // // Use the update plan at the given path. + // optional string plan = 7; + // Run one or more policy packs as part of this update. + repeated PolicyPack policy_pack = 8; + // refresh will run a refresh before the update. + optional bool refresh = 9; + // continue_on_error will continue to perform the update operation despite the + // occurrence of errors. + optional bool continue_on_error = 10; +} + +message UpStream { + oneof response { + // describes a Pulumi engine event, such as a change to a resource or + // diagnostic message. + google.protobuf.Struct event = 1; + UpResult result = 2; + } +} + +message UpResult { + string stdout = 1; + string stderr = 2; + UpdateSummary summary = 3; + optional string permalink = 4; +} + +message UpdateSummary { + google.protobuf.Timestamp start_time = 1; + google.protobuf.Timestamp end_time = 2; + string result = 3; + string message = 4; +} + +message DestroyRequest { + // Parallel is the number of resource operations to run in parallel at once + // (1 for no parallelism). Defaults to unbounded. (default 2147483647) + optional int32 parallel = 1; + // Message (optional) to associate with the destroy operation + optional string message = 2; + // Specify an exclusive list of resource URNs to destroy + repeated string target = 3; + // Allows updating of dependent targets discovered but not specified in the + // Target list + optional bool target_dependents = 4; + // Refresh will run a refresh before the destroy. + optional bool refresh = 5; + // continue_on_error will continue to perform the update operation despite the + // occurrence of errors. + optional bool continue_on_error = 6; + // Remove the stack and its configuration after all resources in the stack + // have been deleted. + optional bool remove = 7; +} + +message DestroyStream { + oneof response { + // describes a Pulumi engine event, such as a change to a resource or + // diagnostic message. + google.protobuf.Struct event = 1; + DestroyResult result = 2; + } +} + +message DestroyResult { + string stdout = 1; + string stderr = 2; + UpdateSummary summary = 3; + optional string permalink = 4; +} diff --git a/agent/pkg/proto/agent_grpc.pb.go b/agent/pkg/proto/agent_grpc.pb.go new file mode 100644 index 00000000..2ae66af3 --- /dev/null +++ b/agent/pkg/proto/agent_grpc.pb.go @@ -0,0 +1,567 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.4.0 +// - protoc v5.27.1 +// source: agent.proto + +package proto + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.62.0 or later. +const _ = grpc.SupportPackageIsVersion8 + +const ( + AutomationService_WhoAmI_FullMethodName = "/agent.AutomationService/WhoAmI" + AutomationService_SelectStack_FullMethodName = "/agent.AutomationService/SelectStack" + AutomationService_Info_FullMethodName = "/agent.AutomationService/Info" + AutomationService_SetAllConfig_FullMethodName = "/agent.AutomationService/SetAllConfig" + AutomationService_Install_FullMethodName = "/agent.AutomationService/Install" + AutomationService_Preview_FullMethodName = "/agent.AutomationService/Preview" + AutomationService_Refresh_FullMethodName = "/agent.AutomationService/Refresh" + AutomationService_Up_FullMethodName = "/agent.AutomationService/Up" + AutomationService_Destroy_FullMethodName = "/agent.AutomationService/Destroy" +) + +// AutomationServiceClient is the client API for AutomationService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type AutomationServiceClient interface { + // * + // WhoAmI returns detailed information about the currently logged-in Pulumi + // identity. + WhoAmI(ctx context.Context, in *WhoAmIRequest, opts ...grpc.CallOption) (*WhoAmIResult, error) + // * + // Info returns information about the given stack. + SelectStack(ctx context.Context, in *SelectStackRequest, opts ...grpc.CallOption) (*SelectStackResult, error) + // * + // Info returns information about the given stack. + Info(ctx context.Context, in *InfoRequest, opts ...grpc.CallOption) (*InfoResult, error) + // * + // SetAllConfig sets multiple configuration values for a stack. + SetAllConfig(ctx context.Context, in *SetAllConfigRequest, opts ...grpc.CallOption) (*SetAllConfigResult, error) + // * + // Install installs the Pulumi plugins and dependencies. + Install(ctx context.Context, in *InstallRequest, opts ...grpc.CallOption) (*InstallResult, error) + // * + // Preview performs a dry-run update to a stack, returning the expected + // changes. + Preview(ctx context.Context, in *PreviewRequest, opts ...grpc.CallOption) (AutomationService_PreviewClient, error) + // * + // Refresh updates the resources in a stack to match the current state of the + // cloud provider. + Refresh(ctx context.Context, in *RefreshRequest, opts ...grpc.CallOption) (AutomationService_RefreshClient, error) + // * + // Up creates or updates the resources in a stack, returning the actual + // changes. + Up(ctx context.Context, in *UpRequest, opts ...grpc.CallOption) (AutomationService_UpClient, error) + // * + // Destroy deletes all resources in a stack. + Destroy(ctx context.Context, in *DestroyRequest, opts ...grpc.CallOption) (AutomationService_DestroyClient, error) +} + +type automationServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewAutomationServiceClient(cc grpc.ClientConnInterface) AutomationServiceClient { + return &automationServiceClient{cc} +} + +func (c *automationServiceClient) WhoAmI(ctx context.Context, in *WhoAmIRequest, opts ...grpc.CallOption) (*WhoAmIResult, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(WhoAmIResult) + err := c.cc.Invoke(ctx, AutomationService_WhoAmI_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *automationServiceClient) SelectStack(ctx context.Context, in *SelectStackRequest, opts ...grpc.CallOption) (*SelectStackResult, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(SelectStackResult) + err := c.cc.Invoke(ctx, AutomationService_SelectStack_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *automationServiceClient) Info(ctx context.Context, in *InfoRequest, opts ...grpc.CallOption) (*InfoResult, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(InfoResult) + err := c.cc.Invoke(ctx, AutomationService_Info_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *automationServiceClient) SetAllConfig(ctx context.Context, in *SetAllConfigRequest, opts ...grpc.CallOption) (*SetAllConfigResult, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(SetAllConfigResult) + err := c.cc.Invoke(ctx, AutomationService_SetAllConfig_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *automationServiceClient) Install(ctx context.Context, in *InstallRequest, opts ...grpc.CallOption) (*InstallResult, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(InstallResult) + err := c.cc.Invoke(ctx, AutomationService_Install_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *automationServiceClient) Preview(ctx context.Context, in *PreviewRequest, opts ...grpc.CallOption) (AutomationService_PreviewClient, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + stream, err := c.cc.NewStream(ctx, &AutomationService_ServiceDesc.Streams[0], AutomationService_Preview_FullMethodName, cOpts...) + if err != nil { + return nil, err + } + x := &automationServicePreviewClient{ClientStream: stream} + if err := x.ClientStream.SendMsg(in); err != nil { + return nil, err + } + if err := x.ClientStream.CloseSend(); err != nil { + return nil, err + } + return x, nil +} + +type AutomationService_PreviewClient interface { + Recv() (*PreviewStream, error) + grpc.ClientStream +} + +type automationServicePreviewClient struct { + grpc.ClientStream +} + +func (x *automationServicePreviewClient) Recv() (*PreviewStream, error) { + m := new(PreviewStream) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +func (c *automationServiceClient) Refresh(ctx context.Context, in *RefreshRequest, opts ...grpc.CallOption) (AutomationService_RefreshClient, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + stream, err := c.cc.NewStream(ctx, &AutomationService_ServiceDesc.Streams[1], AutomationService_Refresh_FullMethodName, cOpts...) + if err != nil { + return nil, err + } + x := &automationServiceRefreshClient{ClientStream: stream} + if err := x.ClientStream.SendMsg(in); err != nil { + return nil, err + } + if err := x.ClientStream.CloseSend(); err != nil { + return nil, err + } + return x, nil +} + +type AutomationService_RefreshClient interface { + Recv() (*RefreshStream, error) + grpc.ClientStream +} + +type automationServiceRefreshClient struct { + grpc.ClientStream +} + +func (x *automationServiceRefreshClient) Recv() (*RefreshStream, error) { + m := new(RefreshStream) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +func (c *automationServiceClient) Up(ctx context.Context, in *UpRequest, opts ...grpc.CallOption) (AutomationService_UpClient, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + stream, err := c.cc.NewStream(ctx, &AutomationService_ServiceDesc.Streams[2], AutomationService_Up_FullMethodName, cOpts...) + if err != nil { + return nil, err + } + x := &automationServiceUpClient{ClientStream: stream} + if err := x.ClientStream.SendMsg(in); err != nil { + return nil, err + } + if err := x.ClientStream.CloseSend(); err != nil { + return nil, err + } + return x, nil +} + +type AutomationService_UpClient interface { + Recv() (*UpStream, error) + grpc.ClientStream +} + +type automationServiceUpClient struct { + grpc.ClientStream +} + +func (x *automationServiceUpClient) Recv() (*UpStream, error) { + m := new(UpStream) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +func (c *automationServiceClient) Destroy(ctx context.Context, in *DestroyRequest, opts ...grpc.CallOption) (AutomationService_DestroyClient, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + stream, err := c.cc.NewStream(ctx, &AutomationService_ServiceDesc.Streams[3], AutomationService_Destroy_FullMethodName, cOpts...) + if err != nil { + return nil, err + } + x := &automationServiceDestroyClient{ClientStream: stream} + if err := x.ClientStream.SendMsg(in); err != nil { + return nil, err + } + if err := x.ClientStream.CloseSend(); err != nil { + return nil, err + } + return x, nil +} + +type AutomationService_DestroyClient interface { + Recv() (*DestroyStream, error) + grpc.ClientStream +} + +type automationServiceDestroyClient struct { + grpc.ClientStream +} + +func (x *automationServiceDestroyClient) Recv() (*DestroyStream, error) { + m := new(DestroyStream) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +// AutomationServiceServer is the server API for AutomationService service. +// All implementations must embed UnimplementedAutomationServiceServer +// for forward compatibility +type AutomationServiceServer interface { + // * + // WhoAmI returns detailed information about the currently logged-in Pulumi + // identity. + WhoAmI(context.Context, *WhoAmIRequest) (*WhoAmIResult, error) + // * + // Info returns information about the given stack. + SelectStack(context.Context, *SelectStackRequest) (*SelectStackResult, error) + // * + // Info returns information about the given stack. + Info(context.Context, *InfoRequest) (*InfoResult, error) + // * + // SetAllConfig sets multiple configuration values for a stack. + SetAllConfig(context.Context, *SetAllConfigRequest) (*SetAllConfigResult, error) + // * + // Install installs the Pulumi plugins and dependencies. + Install(context.Context, *InstallRequest) (*InstallResult, error) + // * + // Preview performs a dry-run update to a stack, returning the expected + // changes. + Preview(*PreviewRequest, AutomationService_PreviewServer) error + // * + // Refresh updates the resources in a stack to match the current state of the + // cloud provider. + Refresh(*RefreshRequest, AutomationService_RefreshServer) error + // * + // Up creates or updates the resources in a stack, returning the actual + // changes. + Up(*UpRequest, AutomationService_UpServer) error + // * + // Destroy deletes all resources in a stack. + Destroy(*DestroyRequest, AutomationService_DestroyServer) error + mustEmbedUnimplementedAutomationServiceServer() +} + +// UnimplementedAutomationServiceServer must be embedded to have forward compatible implementations. +type UnimplementedAutomationServiceServer struct { +} + +func (UnimplementedAutomationServiceServer) WhoAmI(context.Context, *WhoAmIRequest) (*WhoAmIResult, error) { + return nil, status.Errorf(codes.Unimplemented, "method WhoAmI not implemented") +} +func (UnimplementedAutomationServiceServer) SelectStack(context.Context, *SelectStackRequest) (*SelectStackResult, error) { + return nil, status.Errorf(codes.Unimplemented, "method SelectStack not implemented") +} +func (UnimplementedAutomationServiceServer) Info(context.Context, *InfoRequest) (*InfoResult, error) { + return nil, status.Errorf(codes.Unimplemented, "method Info not implemented") +} +func (UnimplementedAutomationServiceServer) SetAllConfig(context.Context, *SetAllConfigRequest) (*SetAllConfigResult, error) { + return nil, status.Errorf(codes.Unimplemented, "method SetAllConfig not implemented") +} +func (UnimplementedAutomationServiceServer) Install(context.Context, *InstallRequest) (*InstallResult, error) { + return nil, status.Errorf(codes.Unimplemented, "method Install not implemented") +} +func (UnimplementedAutomationServiceServer) Preview(*PreviewRequest, AutomationService_PreviewServer) error { + return status.Errorf(codes.Unimplemented, "method Preview not implemented") +} +func (UnimplementedAutomationServiceServer) Refresh(*RefreshRequest, AutomationService_RefreshServer) error { + return status.Errorf(codes.Unimplemented, "method Refresh not implemented") +} +func (UnimplementedAutomationServiceServer) Up(*UpRequest, AutomationService_UpServer) error { + return status.Errorf(codes.Unimplemented, "method Up not implemented") +} +func (UnimplementedAutomationServiceServer) Destroy(*DestroyRequest, AutomationService_DestroyServer) error { + return status.Errorf(codes.Unimplemented, "method Destroy not implemented") +} +func (UnimplementedAutomationServiceServer) mustEmbedUnimplementedAutomationServiceServer() {} + +// UnsafeAutomationServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to AutomationServiceServer will +// result in compilation errors. +type UnsafeAutomationServiceServer interface { + mustEmbedUnimplementedAutomationServiceServer() +} + +func RegisterAutomationServiceServer(s grpc.ServiceRegistrar, srv AutomationServiceServer) { + s.RegisterService(&AutomationService_ServiceDesc, srv) +} + +func _AutomationService_WhoAmI_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(WhoAmIRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AutomationServiceServer).WhoAmI(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: AutomationService_WhoAmI_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AutomationServiceServer).WhoAmI(ctx, req.(*WhoAmIRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _AutomationService_SelectStack_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(SelectStackRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AutomationServiceServer).SelectStack(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: AutomationService_SelectStack_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AutomationServiceServer).SelectStack(ctx, req.(*SelectStackRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _AutomationService_Info_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(InfoRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AutomationServiceServer).Info(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: AutomationService_Info_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AutomationServiceServer).Info(ctx, req.(*InfoRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _AutomationService_SetAllConfig_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(SetAllConfigRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AutomationServiceServer).SetAllConfig(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: AutomationService_SetAllConfig_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AutomationServiceServer).SetAllConfig(ctx, req.(*SetAllConfigRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _AutomationService_Install_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(InstallRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AutomationServiceServer).Install(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: AutomationService_Install_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AutomationServiceServer).Install(ctx, req.(*InstallRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _AutomationService_Preview_Handler(srv interface{}, stream grpc.ServerStream) error { + m := new(PreviewRequest) + if err := stream.RecvMsg(m); err != nil { + return err + } + return srv.(AutomationServiceServer).Preview(m, &automationServicePreviewServer{ServerStream: stream}) +} + +type AutomationService_PreviewServer interface { + Send(*PreviewStream) error + grpc.ServerStream +} + +type automationServicePreviewServer struct { + grpc.ServerStream +} + +func (x *automationServicePreviewServer) Send(m *PreviewStream) error { + return x.ServerStream.SendMsg(m) +} + +func _AutomationService_Refresh_Handler(srv interface{}, stream grpc.ServerStream) error { + m := new(RefreshRequest) + if err := stream.RecvMsg(m); err != nil { + return err + } + return srv.(AutomationServiceServer).Refresh(m, &automationServiceRefreshServer{ServerStream: stream}) +} + +type AutomationService_RefreshServer interface { + Send(*RefreshStream) error + grpc.ServerStream +} + +type automationServiceRefreshServer struct { + grpc.ServerStream +} + +func (x *automationServiceRefreshServer) Send(m *RefreshStream) error { + return x.ServerStream.SendMsg(m) +} + +func _AutomationService_Up_Handler(srv interface{}, stream grpc.ServerStream) error { + m := new(UpRequest) + if err := stream.RecvMsg(m); err != nil { + return err + } + return srv.(AutomationServiceServer).Up(m, &automationServiceUpServer{ServerStream: stream}) +} + +type AutomationService_UpServer interface { + Send(*UpStream) error + grpc.ServerStream +} + +type automationServiceUpServer struct { + grpc.ServerStream +} + +func (x *automationServiceUpServer) Send(m *UpStream) error { + return x.ServerStream.SendMsg(m) +} + +func _AutomationService_Destroy_Handler(srv interface{}, stream grpc.ServerStream) error { + m := new(DestroyRequest) + if err := stream.RecvMsg(m); err != nil { + return err + } + return srv.(AutomationServiceServer).Destroy(m, &automationServiceDestroyServer{ServerStream: stream}) +} + +type AutomationService_DestroyServer interface { + Send(*DestroyStream) error + grpc.ServerStream +} + +type automationServiceDestroyServer struct { + grpc.ServerStream +} + +func (x *automationServiceDestroyServer) Send(m *DestroyStream) error { + return x.ServerStream.SendMsg(m) +} + +// AutomationService_ServiceDesc is the grpc.ServiceDesc for AutomationService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var AutomationService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "agent.AutomationService", + HandlerType: (*AutomationServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "WhoAmI", + Handler: _AutomationService_WhoAmI_Handler, + }, + { + MethodName: "SelectStack", + Handler: _AutomationService_SelectStack_Handler, + }, + { + MethodName: "Info", + Handler: _AutomationService_Info_Handler, + }, + { + MethodName: "SetAllConfig", + Handler: _AutomationService_SetAllConfig_Handler, + }, + { + MethodName: "Install", + Handler: _AutomationService_Install_Handler, + }, + }, + Streams: []grpc.StreamDesc{ + { + StreamName: "Preview", + Handler: _AutomationService_Preview_Handler, + ServerStreams: true, + }, + { + StreamName: "Refresh", + Handler: _AutomationService_Refresh_Handler, + ServerStreams: true, + }, + { + StreamName: "Up", + Handler: _AutomationService_Up_Handler, + ServerStreams: true, + }, + { + StreamName: "Destroy", + Handler: _AutomationService_Destroy_Handler, + ServerStreams: true, + }, + }, + Metadata: "agent.proto", +} diff --git a/agent/pkg/server/server.go b/agent/pkg/server/server.go new file mode 100644 index 00000000..db65efe4 --- /dev/null +++ b/agent/pkg/server/server.go @@ -0,0 +1,698 @@ +/* +Copyright © 2024 Pulumi Corporation + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +package server + +import ( + "context" + "encoding/json" + "fmt" + "os" + "sync" + "time" + + pb "github.com/pulumi/pulumi-kubernetes-operator/agent/pkg/proto" + "go.uber.org/zap" + "go.uber.org/zap/zapio" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + "google.golang.org/protobuf/types/known/structpb" + "google.golang.org/protobuf/types/known/timestamppb" + "k8s.io/utils/ptr" + + "github.com/pulumi/pulumi/sdk/v3/go/auto" + "github.com/pulumi/pulumi/sdk/v3/go/auto/events" + "github.com/pulumi/pulumi/sdk/v3/go/auto/optdestroy" + "github.com/pulumi/pulumi/sdk/v3/go/auto/optpreview" + "github.com/pulumi/pulumi/sdk/v3/go/auto/optrefresh" + "github.com/pulumi/pulumi/sdk/v3/go/auto/optup" + "github.com/pulumi/pulumi/sdk/v3/go/common/apitype" +) + +const ( + UserAgent = "pulumi-kubernetes-operator" +) + +type Server struct { + log *zap.SugaredLogger + plog *zap.Logger + cancelCtx context.Context + cancelFunc context.CancelFunc + ws auto.Workspace + stackLock sync.Mutex + stack *auto.Stack + + pb.UnimplementedAutomationServiceServer +} + +var _ = pb.AutomationServiceServer(&Server{}) + +type Options struct { + // StackName is the name of the stack to upsert (optional). + StackName string + // SecretsProvider is the secrets provider to use for new stacks (optional). + SecretsProvider string +} + +// NewServer creates a new automation server for the given workspace. +func NewServer(ctx context.Context, ws auto.Workspace, opts *Options) (*Server, error) { + if opts == nil { + opts = &Options{} + } + + // create loggers for the server methods and for capturing pulumi logs + log := zap.L().Named("server").Sugar() + plog := zap.L().Named("pulumi") + + // create a context for sending SIGINT to any outstanding Pulumi operations + cancelCtx, cancelFunc := context.WithCancel(ctx) + + server := &Server{ + log: log, + plog: plog, + ws: ws, + cancelCtx: cancelCtx, + cancelFunc: cancelFunc, + } + + // select the initial stack, if provided + if opts.StackName != "" { + stack, err := auto.UpsertStack(ctx, opts.StackName, ws) + if err != nil { + return nil, fmt.Errorf("failed to select stack: %w", err) + } + if opts.SecretsProvider != "" { + err = stack.ChangeSecretsProvider(ctx, opts.SecretsProvider, &auto.ChangeSecretsProviderOptions{}) + if err != nil { + return nil, fmt.Errorf("failed to set secrets provider: %w", err) + } + } + server.stack = &stack + server.log.Infow("selected a stack", "name", stack.Name()) + } + + proj, err := ws.ProjectSettings(ctx) + if err != nil { + return nil, fmt.Errorf("unable to load project: %w", err) + } + log.Infow("project serving", "project", proj.Name, "runtime", proj.Runtime.Name()) + + return server, nil +} + +func (s *Server) ensureStack(ctx context.Context) (auto.Stack, error) { + s.stackLock.Lock() + defer s.stackLock.Unlock() + + summary, err := s.ws.Stack(ctx) + if err != nil { + return auto.Stack{}, err + } + if summary == nil { + return auto.Stack{}, status.Error(codes.FailedPrecondition, "no stack is selected") + } + if s.stack != nil && s.stack.Name() == summary.Name { + return *s.stack, nil + } + return auto.SelectStack(ctx, summary.Name, s.ws) +} + +func (s *Server) clearStack() { + s.stackLock.Lock() + defer s.stackLock.Unlock() + s.stack = nil +} + +// Cancel cancels outstanding operations by sending a SIGINT to Pulumi. +// This call is advisory and non-blocking. +func (s *Server) Cancel() { + s.cancelFunc() +} + +func (s *Server) WhoAmI(ctx context.Context, in *pb.WhoAmIRequest) (*pb.WhoAmIResult, error) { + whoami, err := s.ws.WhoAmIDetails(ctx) + if err != nil { + return nil, err + } + resp := &pb.WhoAmIResult{ + User: whoami.User, + Organizations: whoami.Organizations, + Url: whoami.URL, + } + return resp, nil +} + +func (s *Server) SelectStack(ctx context.Context, in *pb.SelectStackRequest) (*pb.SelectStackResult, error) { + if in.StackName == "" { + return nil, status.Error(codes.InvalidArgument, "invalid stack name") + } + stack, err := func() (auto.Stack, error) { + stack, err := auto.SelectStack(ctx, in.StackName, s.ws) + if err != nil { + if auto.IsSelectStack404Error(err) { + if !in.GetCreate() { + return auto.Stack{}, status.Error(codes.NotFound, "stack not found") + } + return auto.NewStack(ctx, in.StackName, s.ws) + } + return auto.Stack{}, err + } + return stack, nil + }() + if err != nil { + return nil, err + } + + s.stackLock.Lock() + defer s.stackLock.Unlock() + s.stack = &stack + s.log.Infow("selected a stack", "name", stack.Name()) + + info, err := stack.Info(ctx) + if err != nil { + return nil, err + } + resp := &pb.SelectStackResult{ + Summary: marshalStackSummary(info), + } + return resp, nil +} + +func (s *Server) Info(ctx context.Context, in *pb.InfoRequest) (*pb.InfoResult, error) { + stack, err := s.ensureStack(ctx) + if err != nil { + return nil, err + } + + info, err := stack.Info(ctx) + if err != nil { + return nil, err + } + + resp := &pb.InfoResult{ + Summary: marshalStackSummary(info), + } + return resp, nil +} + +func (s *Server) SetAllConfig(ctx context.Context, in *pb.SetAllConfigRequest) (*pb.SetAllConfigResult, error) { + stack, err := s.ensureStack(ctx) + if err != nil { + return nil, err + } + + config := make(map[string]auto.ConfigValue) + for k, inv := range in.GetConfig() { + if k == "" { + return nil, status.Errorf(codes.InvalidArgument, "invalid config key: %s", k) + } + v, err := unmarshalConfigValue(inv) + if err != nil { + return nil, err + } + config[k] = v + } + s.log.Debugw("setting all config", "config", config) + + err = stack.SetAllConfigWithOptions(ctx, config, &auto.ConfigOptions{ + Path: in.GetPath(), + }) + if err != nil { + return nil, err + } + + return nil, nil +} + +func (s *Server) Install(ctx context.Context, in *pb.InstallRequest) (*pb.InstallResult, error) { + stdout := &zapio.Writer{Log: s.plog, Level: zap.InfoLevel} + defer stdout.Close() + stderr := &zapio.Writer{Log: s.plog, Level: zap.WarnLevel} + defer stderr.Close() + opts := &auto.InstallOptions{ + Stdout: stdout, + Stderr: stderr, + } + + s.log.Infow("installing the project dependencies") + if err := s.ws.Install(ctx, opts); err != nil { + s.log.Errorw("install completed with an error", zap.Error(err)) + return nil, status.Error(codes.Aborted, err.Error()) + } + s.log.Infow("installation completed") + + resp := &pb.InstallResult{} + return resp, nil +} + +// Preview implements proto.AutomationServiceServer. +func (s *Server) Preview(in *pb.PreviewRequest, srv pb.AutomationService_PreviewServer) error { + ctx := srv.Context() + stack, err := s.ensureStack(ctx) + if err != nil { + return err + } + + // determine the options to pass to the preview operation + opts := []optpreview.Option{ + optpreview.UserAgent(UserAgent), + optpreview.Diff(), /* richer result? */ + } + if in.Parallel != nil { + opts = append(opts, optpreview.Parallel(int(*in.Parallel))) + } + if in.GetExpectNoChanges() { + opts = append(opts, optpreview.ExpectNoChanges()) + } + if in.Replace != nil { + opts = append(opts, optpreview.Replace(in.Replace)) + } + if in.Target != nil { + opts = append(opts, optpreview.Target(in.Target)) + } + if in.GetTargetDependents() { + opts = append(opts, optpreview.TargetDependents()) + } + // TODO:PolicyPack + if in.GetRefresh() { + opts = append(opts, optpreview.Refresh()) + } + if in.Message != nil { + opts = append(opts, optpreview.Message(*in.Message)) + } + + // wire up the logging + stdout := &zapio.Writer{Log: s.plog, Level: zap.InfoLevel} + defer stdout.Close() + opts = append(opts, optpreview.ProgressStreams(stdout)) + stderr := &zapio.Writer{Log: s.plog, Level: zap.WarnLevel} + defer stderr.Close() + opts = append(opts, optpreview.ErrorProgressStreams(stderr)) + + // stream the engine events to the client + events := make(chan events.EngineEvent) + opts = append(opts, optpreview.EventStreams(events)) + go func() { + for evt := range events { + data, err := marshalEngineEvent(evt.EngineEvent) + if err != nil { + s.log.Errorw("failed to marshal an engine event", "sequence", evt.Sequence, zap.Error(err)) + continue + } + msg := &pb.PreviewStream{Response: &pb.PreviewStream_Event{Event: data}} + if err := srv.Send(msg); err != nil { + s.log.Errorw("failed to send an engine event", "sequence", evt.Sequence, zap.Error(err)) + continue + } + } + }() + + res, err := stack.Preview(ctx, opts...) + if err != nil { + s.log.Errorw("preview completed with an error", zap.Error(err)) + return err + } + stdout.Close() + stderr.Close() + s.log.Infow("preview completed", "summary", res.ChangeSummary) + + resp := &pb.PreviewResult{ + Stdout: res.StdOut, + Stderr: res.StdErr, + } + // TODO: ChangeSummary + permalink, err := res.GetPermalink() + if err != nil && err != auto.ErrParsePermalinkFailed { + return err + } + if permalink != "" { + resp.Permalink = ptr.To(permalink) + } + + msg := &pb.PreviewStream{Response: &pb.PreviewStream_Result{Result: resp}} + if err := srv.Send(msg); err != nil { + s.log.Errorw("unable to send the preview result", zap.Error(err)) + return err + } + return nil +} + +// Refresh implements proto.AutomationServiceServer. +func (s *Server) Refresh(in *pb.RefreshRequest, srv pb.AutomationService_RefreshServer) error { + ctx := srv.Context() + stack, err := s.ensureStack(ctx) + if err != nil { + return err + } + + // determine the options to pass to the preview operation + opts := []optrefresh.Option{ + optrefresh.UserAgent(UserAgent), + } + if in.Parallel != nil { + opts = append(opts, optrefresh.Parallel(int(*in.Parallel))) + } + if in.Message != nil { + opts = append(opts, optrefresh.Message(*in.Message)) + } + if in.GetExpectNoChanges() { + opts = append(opts, optrefresh.ExpectNoChanges()) + } + if in.Target != nil { + opts = append(opts, optrefresh.Target(in.Target)) + } + + // wire up the logging + stdout := &zapio.Writer{Log: s.plog, Level: zap.InfoLevel} + defer stdout.Close() + opts = append(opts, optrefresh.ProgressStreams(stdout)) + stderr := &zapio.Writer{Log: s.plog, Level: zap.WarnLevel} + defer stderr.Close() + opts = append(opts, optrefresh.ErrorProgressStreams(stderr)) + + // stream the engine events to the client + events := make(chan events.EngineEvent) + opts = append(opts, optrefresh.EventStreams(events)) + go func() { + for evt := range events { + data, err := marshalEngineEvent(evt.EngineEvent) + if err != nil { + s.log.Errorw("failed to marshal an engine event", "sequence", evt.Sequence, zap.Error(err)) + continue + } + msg := &pb.RefreshStream{Response: &pb.RefreshStream_Event{Event: data}} + if err := srv.Send(msg); err != nil { + s.log.Errorw("failed to send an engine event", "sequence", evt.Sequence, zap.Error(err)) + continue + } + } + }() + + res, err := stack.Refresh(ctx, opts...) + if err != nil { + s.log.Errorw("refresh completed with an error", zap.Error(err)) + return err + } + s.log.Infow("refresh completed", "summary", res.Summary) + + resp := &pb.RefreshResult{ + Stdout: res.StdOut, + Stderr: res.StdErr, + Summary: marshalUpdateSummary(res.Summary), + } + permalink, err := res.GetPermalink() + if err != nil && err != auto.ErrParsePermalinkFailed { + return err + } + if permalink != "" { + resp.Permalink = ptr.To(permalink) + } + + msg := &pb.RefreshStream{Response: &pb.RefreshStream_Result{Result: resp}} + if err := srv.Send(msg); err != nil { + s.log.Errorw("unable to send the refresh result", zap.Error(err)) + return err + } + return nil +} + +// Up implements proto.AutomationServiceServer. +func (s *Server) Up(in *pb.UpRequest, srv pb.AutomationService_UpServer) error { + ctx := srv.Context() + stack, err := s.ensureStack(ctx) + if err != nil { + return err + } + + // determine the options to pass to the preview operation + opts := []optup.Option{ + optup.UserAgent(UserAgent), + optup.SuppressProgress(), + optup.Diff(), /* richer result? */ + } + if in.Parallel != nil { + opts = append(opts, optup.Parallel(int(*in.Parallel))) + } + if in.Message != nil { + opts = append(opts, optup.Message(*in.Message)) + } + if in.GetExpectNoChanges() { + opts = append(opts, optup.ExpectNoChanges()) + } + if in.Replace != nil { + opts = append(opts, optup.Replace(in.Replace)) + } + if in.Target != nil { + opts = append(opts, optup.Target(in.Target)) + } + if in.GetTargetDependents() { + opts = append(opts, optup.TargetDependents()) + } + // TODO:PolicyPack + if in.GetRefresh() { + opts = append(opts, optup.Refresh()) + } + if in.GetContinueOnError() { + opts = append(opts, optup.ContinueOnError()) + } + + // wire up the logging + stdout := &zapio.Writer{Log: s.plog, Level: zap.InfoLevel} + defer stdout.Close() + stderr := &zapio.Writer{Log: s.plog, Level: zap.WarnLevel} + defer stderr.Close() + opts = append(opts, optup.ProgressStreams(stdout)) + opts = append(opts, optup.ErrorProgressStreams(stderr)) + + // stream the engine events to the client + events := make(chan events.EngineEvent) + opts = append(opts, optup.EventStreams(events)) + go func() { + for evt := range events { + data, err := marshalEngineEvent(evt.EngineEvent) + if err != nil { + s.log.Errorw("failed to marshal an engine event", "sequence", evt.Sequence, zap.Error(err)) + continue + } + msg := &pb.UpStream{Response: &pb.UpStream_Event{Event: data}} + if err := srv.Send(msg); err != nil { + s.log.Errorw("failed to send an engine event", "sequence", evt.Sequence, zap.Error(err)) + continue + } + } + }() + + // run the update to deploy our program + res, err := stack.Up(ctx, opts...) + if err != nil { + s.log.Errorw("up completed with an error", zap.Error(err)) + return err + } + stdout.Close() + stderr.Close() + + s.log.Infow("up completed", "summary", res.Summary) + + resp := &pb.UpResult{ + Stdout: res.StdOut, + Stderr: res.StdErr, + Summary: marshalUpdateSummary(res.Summary), + } + permalink, err := res.GetPermalink() + if err != nil && err != auto.ErrParsePermalinkFailed { + return err + } + if permalink != "" { + resp.Permalink = ptr.To(permalink) + } + + msg := &pb.UpStream{Response: &pb.UpStream_Result{Result: resp}} + if err := srv.Send(msg); err != nil { + s.log.Errorw("unable to send the up result", zap.Error(err)) + return err + } + + return nil +} + +// Destroy implements proto.AutomationServiceServer. +func (s *Server) Destroy(in *pb.DestroyRequest, srv pb.AutomationService_DestroyServer) error { + ctx := srv.Context() + stack, err := s.ensureStack(ctx) + if err != nil { + return err + } + + // determine the options to pass to the preview operation + opts := []optdestroy.Option{ + optdestroy.UserAgent(UserAgent), + } + if in.Parallel != nil { + opts = append(opts, optdestroy.Parallel(int(*in.Parallel))) + } + if in.Message != nil { + opts = append(opts, optdestroy.Message(*in.Message)) + } + if in.Target != nil { + opts = append(opts, optdestroy.Target(in.Target)) + } + if in.GetTargetDependents() { + opts = append(opts, optdestroy.TargetDependents()) + } + if in.GetRefresh() { + opts = append(opts, optdestroy.Refresh()) + } + if in.GetContinueOnError() { + opts = append(opts, optdestroy.ContinueOnError()) + } + if in.GetRemove() { + opts = append(opts, optdestroy.Remove()) + } + + // wire up the logging + stdout := &zapio.Writer{Log: s.plog, Level: zap.InfoLevel} + defer stdout.Close() + opts = append(opts, optdestroy.ProgressStreams(stdout)) + stderr := &zapio.Writer{Log: s.plog, Level: zap.WarnLevel} + defer stderr.Close() + opts = append(opts, optdestroy.ErrorProgressStreams(stderr)) + + // stream the engine events to the client + events := make(chan events.EngineEvent) + opts = append(opts, optdestroy.EventStreams(events)) + go func() { + for evt := range events { + data, err := marshalEngineEvent(evt.EngineEvent) + if err != nil { + s.log.Errorw("failed to marshal an engine event", "sequence", evt.Sequence, zap.Error(err)) + continue + } + msg := &pb.DestroyStream{Response: &pb.DestroyStream_Event{Event: data}} + if err := srv.Send(msg); err != nil { + s.log.Errorw("failed to send an engine event", "sequence", evt.Sequence, zap.Error(err)) + continue + } + } + }() + + // run the update to deploy our program + res, err := stack.Destroy(ctx, opts...) + if err != nil { + s.log.Errorw("destroy completed with an error", zap.Error(err)) + return err + } + s.log.Infow("destroy completed", "summary", res.Summary) + + if in.GetRemove() && res.Summary.Result == "succeeded" { + // the stack was removed, so unselect the current stack. + s.clearStack() + } + + resp := &pb.DestroyResult{ + Stdout: res.StdOut, + Stderr: res.StdErr, + Summary: marshalUpdateSummary(res.Summary), + } + permalink, err := res.GetPermalink() + if err != nil && err != auto.ErrParsePermalinkFailed { + return err + } + if permalink != "" { + resp.Permalink = ptr.To(permalink) + } + + msg := &pb.DestroyStream{Response: &pb.DestroyStream_Result{Result: resp}} + if err := srv.Send(msg); err != nil { + s.log.Errorw("unable to send the destroy result", zap.Error(err)) + return err + } + return nil +} + +func unmarshalConfigValue(inv *pb.ConfigValue) (auto.ConfigValue, error) { + v := auto.ConfigValue{ + Secret: inv.GetSecret(), + } + switch vv := inv.V.(type) { + case *pb.ConfigValue_Value: + // FUTURE: use JSON values + v.Value = fmt.Sprintf("%v", vv.Value.AsInterface()) + case *pb.ConfigValue_ValueFrom: + switch from := vv.ValueFrom.F.(type) { + case *pb.ConfigValueFrom_Env: + data, ok := os.LookupEnv(from.Env) + if !ok { + return auto.ConfigValue{}, status.Errorf(codes.InvalidArgument, "missing value for environment variable: %s", from.Env) + } + v.Value = data + case *pb.ConfigValueFrom_Path: + data, err := os.ReadFile(from.Path) + if err != nil { + return auto.ConfigValue{}, status.Errorf(codes.InvalidArgument, "unreadable path: %s", from.Path) + } + v.Value = string(data) + default: + return auto.ConfigValue{}, status.Error(codes.InvalidArgument, "invalid config value") + } + default: + return auto.ConfigValue{}, status.Error(codes.InvalidArgument, "invalid config value") + } + return v, nil +} + +func marshalStackSummary(info auto.StackSummary) *pb.StackSummary { + data := &pb.StackSummary{ + Name: info.Name, + LastUpdate: parseTime(&info.LastUpdate), + UpdateInProgress: info.UpdateInProgress, + Url: ptr.To(info.URL), + } + if info.ResourceCount != nil { + data.ResourceCount = ptr.To(int32(*info.ResourceCount)) + } + return data +} + +func marshalUpdateSummary(info auto.UpdateSummary) *pb.UpdateSummary { + res := &pb.UpdateSummary{ + Result: info.Result, + Message: info.Message, + StartTime: parseTime(&info.StartTime), + EndTime: parseTime(info.EndTime), + } + return res +} + +func parseTime(s *string) *timestamppb.Timestamp { + if s == nil { + return nil + } + t, err := time.Parse(time.RFC3339Nano, *s) + if err != nil { + return nil + } + return timestamppb.New(t) +} + +func marshalEngineEvent(evt apitype.EngineEvent) (*structpb.Struct, error) { + m := make(map[string]any) + j, _ := json.Marshal(evt) + _ = json.Unmarshal(j, &m) + data, err := structpb.NewStruct(m) + if err != nil { + return nil, err + } + return data, nil +} diff --git a/agent/pkg/server/server_test.go b/agent/pkg/server/server_test.go new file mode 100644 index 00000000..14f90004 --- /dev/null +++ b/agent/pkg/server/server_test.go @@ -0,0 +1,809 @@ +package server_test + +import ( + "context" + "fmt" + "os" + "os/user" + "path/filepath" + "sync" + "testing" + + "github.com/gogo/protobuf/proto" + "github.com/onsi/gomega" + "github.com/onsi/gomega/format" + "github.com/onsi/gomega/types" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + "google.golang.org/protobuf/types/known/structpb" + + pb "github.com/pulumi/pulumi-kubernetes-operator/agent/pkg/proto" + "github.com/pulumi/pulumi-kubernetes-operator/agent/pkg/server" + "github.com/pulumi/pulumi/sdk/v3/go/auto" + "github.com/pulumi/pulumi/sdk/v3/go/common/util/fsutil" + "github.com/pulumi/pulumi/sdk/v3/go/common/workspace" +) + +const ( + TestStackName = "test" +) + +func TestNewServer(t *testing.T) { + t.Parallel() + + tests := []struct { + name string + projectDir string + opts *server.Options + wantErr any + }{ + { + name: "simple", + projectDir: "./testdata/simple", + }, + { + name: "uninstallable", + projectDir: "./testdata/uninstallable", + }, + { + name: "empty", + projectDir: "", + wantErr: gomega.ContainSubstring("unable to find project settings in workspace"), + }, + { + name: "new stack", + projectDir: "./testdata/simple", + opts: &server.Options{StackName: "new"}, + }, + } + for _, tt := range tests { + tt := tt + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + g := gomega.NewWithT(t) + + ctx := newContext(t) + ws := newWorkspace(ctx, t, tt.projectDir) + + _, err := server.NewServer(ctx, ws, tt.opts) + if tt.wantErr != nil { + g.Expect(err).To(gomega.MatchError(tt.wantErr)) + } else { + g.Expect(err).ToNot(gomega.HaveOccurred()) + if tt.opts != nil && tt.opts.StackName != "" { + // ensure that the stack was actually selected + current, err := ws.Stack(ctx) + g.Expect(err).ToNot(gomega.HaveOccurred()) + g.Expect(current.Name).To(gomega.Equal(tt.opts.StackName)) + } + } + }) + } +} + +func TestWhoAmI(t *testing.T) { + t.Parallel() + g := gomega.NewWithT(t) + + u, err := user.Current() + g.Expect(err).ToNot(gomega.HaveOccurred()) + + tests := []struct { + name string + req pb.WhoAmIRequest + wantErr any + want string + }{ + { + name: "logged in", + req: pb.WhoAmIRequest{}, + want: u.Username, + }, + } + for _, tt := range tests { + tt := tt + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + g := gomega.NewWithT(t) + ctx := newContext(t) + tc := newTC(ctx, t, tcOptions{ProjectDir: "./testdata/simple"}) + + res, err := tc.server.WhoAmI(ctx, &tt.req) + if tt.wantErr != nil { + g.Expect(err).To(gomega.MatchError(tt.wantErr)) + } else { + g.Expect(err).ToNot(gomega.HaveOccurred()) + g.Expect(res.User).To(gomega.Equal(tt.want)) + } + }) + } +} + +func TestSelectStack(t *testing.T) { + t.Parallel() + + // hasSummary := func(name string) types.GomegaMatcher { + // return gstruct.MatchFields(gstruct.IgnoreExtras, gstruct.Fields{ + // "Summary": gstruct.PointTo(gstruct.MatchFields(gstruct.IgnoreExtras, gstruct.Fields{ + // "Name": gomega.Equal(name), + // })), + // }) + // } + + tests := []struct { + name string + stacks []string + req pb.SelectStackRequest + wantErr any + }{ + { + name: "already selected stack", + stacks: []string{"one"}, + req: pb.SelectStackRequest{ + StackName: "one", + }, + }, + { + name: "existent stack", + stacks: []string{"one", "two"}, + req: pb.SelectStackRequest{ + StackName: "one", + }, + }, + { + name: "non-existent stack", + req: pb.SelectStackRequest{ + StackName: "unexpected", + }, + wantErr: status.Error(codes.NotFound, "stack not found"), + }, + { + name: "non-existent stack with create", + req: pb.SelectStackRequest{ + StackName: "one", + Create: Pointer(true), + }, + }, + } + for _, tt := range tests { + tt := tt + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + g := gomega.NewWithT(t) + ctx := newContext(t) + tc := newTC(ctx, t, tcOptions{ProjectDir: "./testdata/simple", Stacks: tt.stacks}) + + res, err := tc.server.SelectStack(ctx, &tt.req) + if tt.wantErr != nil { + g.Expect(err).To(gomega.MatchError(tt.wantErr)) + } else { + g.Expect(err).ToNot(gomega.HaveOccurred()) + + // check the response for accuracy + g.Expect(res.Summary.Name).To(gomega.Equal(tt.req.StackName)) + + // ensure that the stack was actually selected + current, err := tc.ws.Stack(ctx) + g.Expect(err).ToNot(gomega.HaveOccurred()) + g.Expect(current.Name).To(gomega.Equal(tt.req.StackName)) + } + }) + } +} + +func TestInfo(t *testing.T) { + t.Parallel() + + tests := []struct { + name string + stacks []string + req pb.InfoRequest + want types.GomegaMatcher + wantErr any + }{ + { + name: "no active stack", + stacks: []string{}, + req: pb.InfoRequest{}, + wantErr: status.Error(codes.FailedPrecondition, "no stack is selected"), + }, + { + name: "active stack", + stacks: []string{TestStackName}, + req: pb.InfoRequest{}, + }, + } + for _, tt := range tests { + tt := tt + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + g := gomega.NewWithT(t) + ctx := newContext(t) + tc := newTC(ctx, t, tcOptions{ProjectDir: "./testdata/simple", Stacks: tt.stacks}) + res, err := tc.server.Info(ctx, &tt.req) + if tt.wantErr != nil { + g.Expect(err).To(gomega.MatchError(tt.wantErr)) + } else { + g.Expect(err).ToNot(gomega.HaveOccurred()) + // check the response for accuracy + current, err := tc.ws.Stack(ctx) + g.Expect(err).ToNot(gomega.HaveOccurred()) + g.Expect(res.Summary.Name).To(gomega.Equal(current.Name)) + } + }) + } +} + +func TestSetAllConfig(t *testing.T) { + t.Parallel() + + // SetAllConfig updates the config based on literals, envs, and files + + strVal := structpb.NewStringValue("bar") + boolVal := structpb.NewBoolValue(true) + + tests := []struct { + name string + stacks []string + req pb.SetAllConfigRequest + wantErr any + want auto.ConfigMap + }{ + { + name: "no active stack", + stacks: []string{}, + req: pb.SetAllConfigRequest{}, + wantErr: status.Error(codes.FailedPrecondition, "no stack is selected"), + }, + { + name: "literal", + stacks: []string{TestStackName}, + req: pb.SetAllConfigRequest{ + Config: map[string]*pb.ConfigValue{ + "foo": {V: &pb.ConfigValue_Value{Value: strVal}}, + }, + }, + want: auto.ConfigMap{ + "simple:foo": {Value: "bar"}, + }, + }, + { + name: "env", + stacks: []string{TestStackName}, + req: pb.SetAllConfigRequest{ + // note that TestMain sets the FOO environment variable to a test value + Config: map[string]*pb.ConfigValue{ + "foo": {V: &pb.ConfigValue_ValueFrom{ValueFrom: &pb.ConfigValueFrom{F: &pb.ConfigValueFrom_Env{Env: "FOO"}}}}, + }, + }, + want: auto.ConfigMap{ + "simple:foo": {Value: "bar"}, + }, + }, + { + name: "file", + stacks: []string{TestStackName}, + req: pb.SetAllConfigRequest{ + // note that TestMain sets the FOO environment variable to a test value + Config: map[string]*pb.ConfigValue{ + "foo": {V: &pb.ConfigValue_ValueFrom{ValueFrom: &pb.ConfigValueFrom{F: &pb.ConfigValueFrom_Path{Path: "./testdata/foo.txt"}}}}, + }, + }, + want: auto.ConfigMap{ + "simple:foo": {Value: "bar"}, + }, + }, + { + name: "path-based", + stacks: []string{TestStackName}, + req: pb.SetAllConfigRequest{ + Path: Pointer(true), + Config: map[string]*pb.ConfigValue{ + "a.b": {V: &pb.ConfigValue_Value{Value: strVal}}, + }, + }, + want: auto.ConfigMap{ + "simple:a": {Value: `{"b":"bar"}`}, + }, + }, + { + name: "secret", + stacks: []string{TestStackName}, + req: pb.SetAllConfigRequest{ + Config: map[string]*pb.ConfigValue{ + "foo": {V: &pb.ConfigValue_Value{Value: strVal}, Secret: Pointer(true)}, + }, + }, + want: auto.ConfigMap{ + "simple:foo": {Value: "bar", Secret: true}, + }, + }, + { + name: "typed", + stacks: []string{TestStackName}, + req: pb.SetAllConfigRequest{ + Config: map[string]*pb.ConfigValue{ + "enabled": {V: &pb.ConfigValue_Value{Value: boolVal}}, + }, + }, + want: auto.ConfigMap{ + "simple:enabled": {Value: "true"}, + }, + }, + } + for _, tt := range tests { + tt := tt + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + g := gomega.NewWithT(t) + ctx := newContext(t) + tc := newTC(ctx, t, tcOptions{ProjectDir: "./testdata/simple", Stacks: tt.stacks}) + _, err := tc.server.SetAllConfig(ctx, &tt.req) + if tt.wantErr != nil { + g.Expect(err).To(gomega.MatchError(tt.wantErr)) + } else { + g.Expect(err).ToNot(gomega.HaveOccurred()) + + actual, err := tc.ws.GetAllConfig(ctx, tc.stack.Name()) + g.Expect(err).ToNot(gomega.HaveOccurred()) + g.Expect(actual).To(gomega.Equal(tt.want)) + } + }) + } +} + +func TestInstall(t *testing.T) { + t.Parallel() + + tests := []struct { + name string + projectDir string + req pb.InstallRequest + wantErr types.GomegaMatcher + }{ + { + name: "simple", + projectDir: "./testdata/simple", + req: pb.InstallRequest{}, + }, + { + name: "uninstallable", + projectDir: "./testdata/uninstallable", + req: pb.InstallRequest{}, + wantErr: HasStatusCode(codes.Aborted, gomega.ContainSubstring("go.mod file not found")), + }, + } + for _, tt := range tests { + tt := tt + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + g := gomega.NewWithT(t) + ctx := newContext(t) + tc := newTC(ctx, t, tcOptions{ProjectDir: tt.projectDir}) + _, err := tc.server.Install(ctx, &tt.req) + if tt.wantErr != nil { + g.Expect(err).To(gomega.HaveOccurred()) + g.Expect(err).To(tt.wantErr) + // g.Expect(err).To(gomega.MatchError(tt.wantErr)) + } else { + g.Expect(err).ToNot(gomega.HaveOccurred()) + } + }) + } +} + +func TestUp(t *testing.T) { + t.Parallel() + + tests := []struct { + name string + projectDir string + stacks []string + req pb.UpRequest + wantErr any + want auto.ConfigMap + }{ + { + name: "no active stack", + projectDir: "./testdata/simple", + stacks: []string{}, + req: pb.UpRequest{}, + wantErr: status.Error(codes.FailedPrecondition, "no stack is selected"), + }, + { + name: "simple", + projectDir: "./testdata/simple", + stacks: []string{TestStackName}, + req: pb.UpRequest{}, + }, + } + for _, tt := range tests { + tt := tt + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + g := gomega.NewWithT(t) + ctx := newContext(t) + tc := newTC(ctx, t, tcOptions{ProjectDir: tt.projectDir, Stacks: tt.stacks}) + + srv := &upStream{ + ctx: ctx, + events: make([]structpb.Struct, 0, 100), + } + err := tc.server.Up(&tt.req, srv) + if tt.wantErr != nil { + g.Expect(err).To(gomega.MatchError(tt.wantErr)) + } else { + g.Expect(err).ToNot(gomega.HaveOccurred()) + g.Expect(srv.events).ToNot(gomega.BeEmpty()) + g.Expect(srv.result).ToNot(gomega.BeNil()) + g.Expect(srv.result.Summary).ToNot(gomega.BeNil()) + g.Expect(srv.result.Summary.Result).To(gomega.Equal("succeeded")) + } + }) + } +} + +type upStream struct { + grpc.ServerStream + ctx context.Context + mu sync.RWMutex + events []structpb.Struct + result *pb.UpResult +} + +var _ pb.AutomationService_UpServer = (*upStream)(nil) + +func (m *upStream) Context() context.Context { + return m.ctx +} +func (m *upStream) Send(resp *pb.UpStream) error { + m.mu.Lock() + defer m.mu.Unlock() + switch r := resp.Response.(type) { + case *pb.UpStream_Event: + m.events = append(m.events, *r.Event) + case *pb.UpStream_Result: + m.result = r.Result + } + return nil +} + +func TestPreview(t *testing.T) { + t.Parallel() + + tests := []struct { + name string + projectDir string + stacks []string + req pb.PreviewRequest + wantErr any + want auto.ConfigMap + }{ + { + name: "no active stack", + projectDir: "./testdata/simple", + stacks: []string{}, + req: pb.PreviewRequest{}, + wantErr: status.Error(codes.FailedPrecondition, "no stack is selected"), + }, + { + name: "simple", + projectDir: "./testdata/simple", + stacks: []string{TestStackName}, + req: pb.PreviewRequest{}, + }, + } + for _, tt := range tests { + tt := tt + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + g := gomega.NewWithT(t) + ctx := newContext(t) + tc := newTC(ctx, t, tcOptions{ProjectDir: tt.projectDir, Stacks: tt.stacks}) + + srv := &previewStream{ + ctx: ctx, + events: make([]structpb.Struct, 0, 100), + } + err := tc.server.Preview(&tt.req, srv) + if tt.wantErr != nil { + g.Expect(err).To(gomega.MatchError(tt.wantErr)) + } else { + g.Expect(err).ToNot(gomega.HaveOccurred()) + g.Expect(srv.events).ToNot(gomega.BeEmpty()) + g.Expect(srv.result).ToNot(gomega.BeNil()) + } + }) + } +} + +type previewStream struct { + grpc.ServerStream + ctx context.Context + mu sync.RWMutex + events []structpb.Struct + result *pb.PreviewResult +} + +var _ pb.AutomationService_PreviewServer = (*previewStream)(nil) + +func (m *previewStream) Context() context.Context { + return m.ctx +} +func (m *previewStream) Send(resp *pb.PreviewStream) error { + m.mu.Lock() + defer m.mu.Unlock() + switch r := resp.Response.(type) { + case *pb.PreviewStream_Event: + m.events = append(m.events, *r.Event) + case *pb.PreviewStream_Result: + m.result = r.Result + } + return nil +} + +func TestRefresh(t *testing.T) { + t.Parallel() + + tests := []struct { + name string + projectDir string + stacks []string + req pb.RefreshRequest + wantErr any + want auto.ConfigMap + }{ + { + name: "no active stack", + projectDir: "./testdata/simple", + stacks: []string{}, + req: pb.RefreshRequest{}, + wantErr: status.Error(codes.FailedPrecondition, "no stack is selected"), + }, + { + name: "simple", + projectDir: "./testdata/simple", + stacks: []string{TestStackName}, + req: pb.RefreshRequest{}, + }, + } + for _, tt := range tests { + tt := tt + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + g := gomega.NewWithT(t) + ctx := newContext(t) + tc := newTC(ctx, t, tcOptions{ProjectDir: tt.projectDir, Stacks: tt.stacks}) + + srv := &refreshStream{ + ctx: ctx, + events: make([]structpb.Struct, 0, 100), + } + err := tc.server.Refresh(&tt.req, srv) + if tt.wantErr != nil { + g.Expect(err).To(gomega.MatchError(tt.wantErr)) + } else { + g.Expect(err).ToNot(gomega.HaveOccurred()) + g.Expect(srv.events).ToNot(gomega.BeEmpty()) + g.Expect(srv.result).ToNot(gomega.BeNil()) + g.Expect(srv.result.Summary).ToNot(gomega.BeNil()) + g.Expect(srv.result.Summary.Result).To(gomega.Equal("succeeded")) + } + }) + } +} + +type refreshStream struct { + grpc.ServerStream + ctx context.Context + mu sync.RWMutex + events []structpb.Struct + result *pb.RefreshResult +} + +var _ pb.AutomationService_RefreshServer = (*refreshStream)(nil) + +func (m *refreshStream) Context() context.Context { + return m.ctx +} +func (m *refreshStream) Send(resp *pb.RefreshStream) error { + m.mu.Lock() + defer m.mu.Unlock() + switch r := resp.Response.(type) { + case *pb.RefreshStream_Event: + m.events = append(m.events, *r.Event) + case *pb.RefreshStream_Result: + m.result = r.Result + } + return nil +} + +func TestDestroy(t *testing.T) { + t.Parallel() + + tests := []struct { + name string + projectDir string + stacks []string + req pb.DestroyRequest + wantErr any + want auto.ConfigMap + }{ + { + name: "no active stack", + projectDir: "./testdata/simple", + stacks: []string{}, + req: pb.DestroyRequest{}, + wantErr: status.Error(codes.FailedPrecondition, "no stack is selected"), + }, + { + name: "simple", + projectDir: "./testdata/simple", + stacks: []string{TestStackName}, + req: pb.DestroyRequest{}, + }, + } + for _, tt := range tests { + tt := tt + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + g := gomega.NewWithT(t) + ctx := newContext(t) + tc := newTC(ctx, t, tcOptions{ProjectDir: tt.projectDir, Stacks: tt.stacks}) + + srv := &destroyStream{ + ctx: ctx, + events: make([]structpb.Struct, 0, 100), + } + err := tc.server.Destroy(&tt.req, srv) + if tt.wantErr != nil { + g.Expect(err).To(gomega.MatchError(tt.wantErr)) + } else { + g.Expect(err).ToNot(gomega.HaveOccurred()) + g.Expect(srv.events).ToNot(gomega.BeEmpty()) + g.Expect(srv.result).ToNot(gomega.BeNil()) + g.Expect(srv.result.Summary).ToNot(gomega.BeNil()) + g.Expect(srv.result.Summary.Result).To(gomega.Equal("succeeded")) + } + }) + } +} + +type destroyStream struct { + grpc.ServerStream + ctx context.Context + mu sync.RWMutex + events []structpb.Struct + result *pb.DestroyResult +} + +var _ pb.AutomationService_DestroyServer = (*destroyStream)(nil) + +func (m *destroyStream) Context() context.Context { + return m.ctx +} +func (m *destroyStream) Send(resp *pb.DestroyStream) error { + m.mu.Lock() + defer m.mu.Unlock() + switch r := resp.Response.(type) { + case *pb.DestroyStream_Event: + m.events = append(m.events, *r.Event) + case *pb.DestroyStream_Result: + m.result = r.Result + } + return nil +} + +func newContext(t *testing.T) context.Context { + ctx := context.Background() + if deadline, ok := t.Deadline(); ok { + var cancel context.CancelFunc + ctx, cancel = context.WithDeadline(ctx, deadline) + t.Cleanup(cancel) + } + return ctx +} + +func newWorkspace(ctx context.Context, t *testing.T, templateDir string) auto.Workspace { + opts := []auto.LocalWorkspaceOption{} + + // generate a project based on the template, with a file backend + tempDir := t.TempDir() + if templateDir != "" { + err := os.MkdirAll(filepath.Join(tempDir, ".pulumi"), 0755) + if err != nil { + t.Fatalf("failed to create state backend directory: %v", err) + } + if err := fsutil.CopyFile(tempDir, templateDir, nil); err != nil { + t.Fatalf("failed to copy project file(s): %v", err) + } + proj, err := workspace.LoadProject(filepath.Join(tempDir, "Pulumi.yaml")) + if err != nil { + t.Fatalf("failed to load project: %v", err) + } + proj.Backend = &workspace.ProjectBackend{ + URL: fmt.Sprintf("file://%s", filepath.Join(tempDir, ".pulumi")), + } + err = proj.Save(filepath.Join(tempDir, "Pulumi.yaml")) + if err != nil { + t.Fatalf("failed to save project: %v", err) + } + } + opts = append(opts, auto.WorkDir(tempDir)) + + ws, err := auto.NewLocalWorkspace(ctx, opts...) + if err != nil { + t.Fatalf("failed to create workspace: %v", err) + } + t.Logf("created workspace in %q", tempDir) + + return ws +} + +func Pointer[T any](d T) *T { + return &d +} + +func HasStatusCode(code codes.Code, msg types.GomegaMatcher) types.GomegaMatcher { + return gomega.WithTransform(func(err error) status.Status { + s, _ := status.FromError(err) + return *s + }, gomega.And( + gomega.WithTransform(func(s status.Status) codes.Code { return s.Code() }, gomega.Equal(code)), + gomega.WithTransform(func(s status.Status) string { return s.Message() }, msg), + )) +} + +type testContext struct { + ws auto.Workspace + stack *auto.Stack + server *server.Server +} + +type tcOptions struct { + ProjectDir string + Stacks []string // pre-create some stacks; last one will be selected + ServerOpts *server.Options +} + +func newTC(ctx context.Context, t *testing.T, opts tcOptions) *testContext { + ws := newWorkspace(ctx, t, opts.ProjectDir) + if opts.ServerOpts == nil { + opts.ServerOpts = &server.Options{} + } + server, err := server.NewServer(ctx, ws, opts.ServerOpts) + if err != nil { + t.Fatalf("failed to create server: %v", err) + } + + tc := &testContext{ + ws: ws, + server: server, + } + for _, name := range opts.Stacks { + stack, err := auto.NewStack(ctx, name, ws) + if err != nil { + t.Fatalf("failed to create server: %v", err) + } + tc.stack = &stack + } + return tc +} + +func TestMain(m *testing.M) { + format.RegisterCustomFormatter(func(value interface{}) (string, bool) { + if v, ok := value.(proto.Message); ok { + return v.String(), true + } + return "", false + }) + + // configure the file backend + os.Setenv("PULUMI_CONFIG_PASSPHRASE", "") + + // create a FOO variable for test purposes + os.Setenv("FOO", "bar") + + os.Exit(m.Run()) +} diff --git a/agent/pkg/server/testdata/foo.txt b/agent/pkg/server/testdata/foo.txt new file mode 100644 index 00000000..ba0e162e --- /dev/null +++ b/agent/pkg/server/testdata/foo.txt @@ -0,0 +1 @@ +bar \ No newline at end of file diff --git a/agent/pkg/server/testdata/simple/Pulumi.yaml b/agent/pkg/server/testdata/simple/Pulumi.yaml new file mode 100644 index 00000000..be67d22a --- /dev/null +++ b/agent/pkg/server/testdata/simple/Pulumi.yaml @@ -0,0 +1,2 @@ +name: simple +runtime: yaml diff --git a/agent/pkg/server/testdata/uninstallable/Pulumi.yaml b/agent/pkg/server/testdata/uninstallable/Pulumi.yaml new file mode 100644 index 00000000..e84fab87 --- /dev/null +++ b/agent/pkg/server/testdata/uninstallable/Pulumi.yaml @@ -0,0 +1,3 @@ +name: uninstallable +runtime: go +description: A project that cannot be installed because it lacks a go.mod diff --git a/agent/version/version.go b/agent/version/version.go new file mode 100644 index 00000000..b4ecc8fe --- /dev/null +++ b/agent/version/version.go @@ -0,0 +1,3 @@ +package version + +var Version string = "v0.0.1" diff --git a/go.mod b/go.mod index 45846ccd..b7f2b072 100644 --- a/go.mod +++ b/go.mod @@ -35,7 +35,6 @@ require ( github.com/fluxcd/pkg/http/fetch v0.2.0 github.com/go-git/go-git/v5 v5.12.0 github.com/onsi/ginkgo/v2 v2.3.1 - go.uber.org/mock v0.4.0 sigs.k8s.io/yaml v1.2.0 ) diff --git a/go.sum b/go.sum index 8711054f..237c4e13 100644 --- a/go.sum +++ b/go.sum @@ -1171,8 +1171,6 @@ go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/automaxprocs v1.2.0/go.mod h1:YfO3fm683kQpzETxlTGZhGIVmXAhaw3gxeBADbpZtnU= go.uber.org/goleak v1.1.10 h1:z+mqJhf6ss6BSfSM671tgKyZBFPTTJM+HLxnhPC3wu0= go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= -go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU= -go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= go.uber.org/multierr v0.0.0-20180122172545-ddea229ff1df/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=